# PrepBusiness API Documentation > REST API for fulfillment, inventory, orders, and shipping operations. --- ## Getting Started Take your first steps to integrating with the API The API is a REST API. Generally, we use resource URLs for our endpoints. We accept both form-encoded and JSON inputs, and return JSON-encoded results. The API does not currently have a test environment. ### Base URL The URL for all the endpoints listed in the document follow this pattern: ``` https://YOUR_COMPANY_DOMAIN/api/ENDPOINT ``` So a GET request to list the users of an account would look like this: ``` GET https://portal.yourcompany.com/api/users ``` ### Headers If you are sending JSON data to the API, you must add the Content-Type header to the request: ``` Content-Type: application/json ``` You should also set the Accept header to ensure that you receive a JSON response from the API: ``` Accept: application/json ``` --- ## Authentication A guide on how to authenticate your API requests The API uses API keys to authentication your requests. You can generate an API key for your user account by visiting your user settings page at `YOUR SUBDOMAIN/settings#api`. You can browse there by clicking the user icon at the top left of the page, then clicking Your Settings, then navigating to the API tab. ### Creating a Token To create a token, enter a unique name to help you remember why you created the token. Then, click Create Token. The API token will be displayed on the page, and it will only be displayed once so make sure you copy the value and store it securely. ### Revoking a Token If you are no longer using a token, or if the token has been compromised, you can revoke a token at any time from the same page. Find the token in your list of API tokens and click the red Trash icon. ### Authenticating a Request To authenticate a request to the API, you can either provide the token in the request headers: ``` Authorization: Bearer YOUR_TOKEN ``` or via a request parameter named `api_token`. --- ## Merchant Header Set a header to return results for a specific merchant For any request you make that could involve results from multiple merchants, or for endpoint that require a merchant to be selected, use the `X-Selected-Client-Id` header with the merchant ID as the value of the header. ``` X-Selected-Client-Id: 405 ``` For example, if you would like a list of all outbound shipments but only for a specific merchant, passing their merchant ID in the `X-Selected-Client-Id` parameter will only return shipments related to that merchant. By default, results requested by a service provider will contain records related to all merchants. Note: Merchants making a request to the API almost always need to have this header set. --- ## Pagination Retrieve results when there are multiple pages available Some requests will return a paginated set of results, and you can retrieve more pages by incrementing the `page` query parameter. The data from the request will be returned in the `data` key. The following keys will also be present on the request: `current_page` The page returned in this request `from` The start of the range for this request `to` The end of the range for this request `total` The total number of results available on all pages `last_page` The index of the last page `per_page` The maximum number of results returned per page --- ## Search Language A language to filter results in endpoints that support the search language The search language filter syntax provides a powerful way to filter API results. Use this query language to narrow down results based on specific field values. Use the `q` query parameter to specify the search language filter syntax. Each endpoint has a list of supported fields which you will need to consult to determine which fields are available for filtering. ### Basic Syntax ``` q={FIELD}{OPERATOR}"{VALUE}" {AND|OR} {FIELD}{OPERATOR}"{VALUE}" ... ``` Ensure that the value is enclosed in double quotes. ### Examples ``` name:"John" created_at>"2023-01-01" status!:"inactive" ``` ### Supported Operators - `:` Equals `name:"Smith"` - `!:` Not equals `status!:"deleted"` - `~` Contains `tags~"urgent"` - `!~` Does not contain `description!~"draft"` - `>` Greater than `price>"50"` - `<` Less than `stock<"10"` - `>=` Greater than or equal to `rating>="4"` - `<=` Less than or equal to `priority<="3"` ### Combining Filters Connect multiple conditions using `AND` or `OR`: ``` status:"active" AND created_at>"2023-01-01" priority:"high" OR due_date<:"2023-12-31" ``` ### Relationship Filtering Access related resources using dot notation: ``` user.name:"John" order.items.count>"5" ``` ### Notes Parentheses grouping is not supported All conditions are evaluated left-to-right Values must be enclosed in double quotes ### Example API Usage ``` GET /api/channels/listings?q=title:"Chair" AND title:"Table" ``` --- ## Channels Viewing and managing channels and listings ### List channels **GET** `/channels` #### Expected Response Status: `200` A successful response returning the list of channels Content-Type: `application/json` ```json { "channels": [ { "id": 2, "merchant_id": 2, "team_id": 2, "type": "amazon", "nickname": "Amazon Store", "channel_account_id": "23o-othvv-xkrxh-rlrw", "connection_status": "active", "country_id": "ATVPDKIKX0DER" } ] } ``` ### Create an Amazon channel connection invitation **POST** `/channels/amazon/connection-invitation` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | marketplace | string | Yes | The Amazon marketplace identifier to connect | | nickname | string | No | An optional nickname for the channel | | redirect_url | string | Yes | The URL to redirect the merchant to after they successfully connect their Amazon channel | #### Expected Response Status: `200` A successful response returning the invitation token, expiry, and connection URL Content-Type: `application/json` ```json { "token": "550e8400-e29b-41d4-a716-446655440000", "expires_at": "2026-06-16T12:00:00+00:00", "connection_url": "https://acme.conveyr.com/external-oauth/amazon/channel-connection/550e8400-e29b-41d4-a716-446655440000" } ``` ### Show a channel Get a single channel by its ID. Used to populate the channel edit page. **GET** `/channels/{channel}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the channel | #### Expected Response Status: `200` A successful response returning the channel Content-Type: `application/json` ```json { "channel": { "id": 2, "merchant_id": 2, "team_id": 2, "type": "amazon", "nickname": "Amazon Store", "channel_account_id": "23o-othvv-xkrxh-rlrw", "connection_status": "active", "country_id": "ATVPDKIKX0DER", "created_at": "2026-06-16T12:00:00.000000+00:00", "updated_at": "2026-06-16T12:00:00.000000+00:00" } } ``` ### Delete a channel Delete a channel and its associated listings, listing-product links, and Amazon feeds. **DELETE** `/channels/{channel}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the channel | #### Expected Response Status: `200` A successful response after deleting the channel Content-Type: `application/json` ```json { "message": "Channel deleted" } ``` ### Activate a channel Mark a channel as active. Used on the channel edit page. **GET** `/channels/{channel}/activate` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the channel | #### Expected Response Status: `200` A successful response after activating the channel Content-Type: `application/json` ```json { "message": "Channel activated" } ``` ### Deactivate a channel Deactivate a channel, setting its connection status to `unauthorized`. Used on the channel edit page. **GET** `/channels/{channel}/deactivate` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the channel | #### Expected Response Status: `200` A successful response after deactivating the channel Content-Type: `application/json` ```json { "message": "Channel deactivated" } ``` ### Create an Amazon channel Create a new Amazon channel for the current merchant. The channel is created in an unauthorized state; use the authorize-url endpoint to begin the OAuth flow. **POST** `/channels/amazon` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | marketplace | string | Yes | The Amazon marketplace identifier to connect | | nickname | string | No | An optional nickname for the channel | #### Expected Response Status: `200` A successful response returning the created channel Content-Type: `application/json` ```json { "message": "Channel created", "channel": { "id": 2, "merchant_id": 2, "team_id": 2, "type": "amazon", "nickname": "Amazon Store", "channel_account_id": null, "connection_status": "unauthorized", "country_id": "ATVPDKIKX0DER", "created_at": "2026-06-16T12:00:00.000000+00:00", "updated_at": "2026-06-16T12:00:00.000000+00:00" } } ``` ### Update an Amazon channel Update an Amazon channel's nickname and marketplace. Changing the marketplace disconnects the channel and sets its connection status to `unauthorized`, requiring re-authorization. **PUT** `/channels/amazon/{channel}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Amazon channel | | marketplace | string | Yes | The Amazon marketplace identifier | | nickname | string | No | An optional nickname for the channel | #### Expected Response Status: `200` A successful response after updating the channel Content-Type: `application/json` ```json { "message": "Channel updated" } ``` ### Get the Amazon channel authorize URL Return the Amazon OAuth URL to redirect the merchant to in order to authorize the channel. This is the real "authorize" step of connecting an Amazon channel. **GET** `/channels/amazon/{channel}/authorize-url` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Amazon channel | #### Expected Response Status: `200` A successful response returning the OAuth URL to redirect to Content-Type: `application/json` ```json { "url": "https://sellercentral.amazon.com/apps/authorize/consent?application_id=amzn1.sp.solution.abc&state=xyz" } ``` ### List Amazon marketplaces Return the list of Amazon marketplaces that a channel can be connected to. **GET** `/channels/amazon/marketplaces` #### Expected Response Status: `200` A successful response returning the list of Amazon marketplaces Content-Type: `application/json` ```json [ { "identifier": "ATVPDKIKX0DER", "country": "United States" }, { "identifier": "A2EUQ1WTGCTBG2", "country": "Canada" } ] ``` ### Show a Amazon catalog item's landed-price analytics Summarises daily UTC landed-price observations of the Amazon New featured offer for one Amazon catalog item into calendar buckets over [start, end). Catalog prices are global per platform, so no listing, channel or merchant link is needed; the caller needs listings:view on the narrated account. A uuid that is not an existing Amazon catalog item returns 404. Days are UTC calendar days, weeks start on Monday and months on the first. Edge buckets are clipped to the range. Each observed currency is its own series; an item with no observations in the range returns an empty series array. Averages are per observation, not time-weighted, and the current UTC day may still gain observations. **GET** `/channels/amazon/catalog-items/{catalog_item_uuid}/prices` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | catalog_item_uuid | string | Yes | The Amazon catalog item's uuid | | start | string | Yes | First UTC day to include, as YYYY-MM-DD with a four-digit AD year from 0001 to 9999. | | end | string | Yes | UTC day after the last day to include, as YYYY-MM-DD with a four-digit AD year from 0001 to 9999. Must be after start, at most 731 days later. | | granularity | string | Yes | Bucket size: UTC calendar day, Monday-start week, or calendar month. | #### Expected Response Status: `200` Landed-price buckets per observed currency. Content-Type: `application/json` ```json { "start": "string", "end": "string", "granularity": "day", "timezone": "UTC", "series": [ { "currency": "USD", "buckets": [ { "start": "string", "end": "string", "lowest_landed_price": "string", "highest_landed_price": "string", "average_landed_price": "string", "observation_count": 1, "observed_days": 1 } ] } ] } ``` ### Index an Amazon channel's listing inventory levels Returns one entry per stored AFN or MFN level, so one listing can have two entries. Listings without inventory are omitted and `total` counts levels. Values are retained until replaced: `synced_at` is the source-request time and exposes staleness, while nullable `reported_at` is a legacy vendor timestamp and is not freshness. AFN and MFN may have different ages. This read-only request does not fetch Amazon, inactive channels remain readable, and replica reads may lag recent writes slightly. **GET** `/channels/amazon/{channel}/inventory-levels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Amazon channel | | q | string | No | Search language filter for `listing_id`, `sku`, and `fulfillment_network`. Clauses can be combined with `AND` or `OR`; fragments the search-language parser does not recognize are ignored, while recognized clauses must use a supported field and valid value. Unknown network values simply return no rows. Example: `sku~"WIDGET" AND fulfillment_network:"afn"` | | sorts | array | No | Up to two requested sorts. Defaults to listing_id ascending then fulfillment_network ascending. Requested priorities are normalized and those same tie-breakers are appended, keeping page boundaries stable even for equal SKU or synced_at values. Example: `sorts[0][field]=synced_at&sorts[0][direction]=desc&sorts[0][order]=1`. | | page | integer | No | | | per_page | integer | No | | #### Expected Response Status: `200` A paginated list of stored inventory levels; total counts AFN/MFN level rows Content-Type: `application/json` ```json { "data": [ { "listing_id": 21, "sku": "SD-AB-12345", "fulfillment_network": "afn", "quantity": 12, "total_quantity": 20, "inbound_working_quantity": 2, "inbound_shipped_quantity": 3, "inbound_receiving_quantity": 4, "reserved_quantity": 5, "researching_quantity": 6, "unfulfillable_quantity": 7, "reported_at": "2026-09-01T04:05:12Z", "synced_at": "2026-10-01T04:05:12Z" } ], "total": 42, "current_page": 1, "last_page": 5, "per_page": 10, "from": 1, "to": 10, "first_page_url": "string", "last_page_url": "string", "next_page_url": "string", "prev_page_url": "string", "path": "string", "links": [] } ``` ### Create a custom channel Create a new custom channel for the current merchant. Custom channels are created in an active state. **POST** `/channels/custom` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | nickname | string | Yes | A nickname for the channel | #### Expected Response Status: `200` A successful response returning the created channel Content-Type: `application/json` ```json { "message": "Channel created", "channel": { "id": 3, "merchant_id": 2, "team_id": 2, "type": "custom", "nickname": "My Custom Channel", "connection_status": "active", "created_at": "2026-06-16T12:00:00.000000+00:00", "updated_at": "2026-06-16T12:00:00.000000+00:00" } } ``` ### Update a custom channel Update a custom channel's nickname. **PUT** `/channels/custom/{channel}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the custom channel | | nickname | string | Yes | A nickname for the channel | #### Expected Response Status: `200` A successful response after updating the channel Content-Type: `application/json` ```json { "message": "Channel updated" } ``` ### Create a Walmart channel Create a new Walmart channel for the current merchant. The channel is created in an unauthorized state; use the authorize-url endpoint to begin the OAuth flow. **POST** `/channels/walmart` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | marketplace | string | Yes | The Walmart marketplace to connect | | nickname | string | No | An optional nickname for the channel | #### Expected Response Status: `200` A successful response returning the created channel Content-Type: `application/json` ```json { "message": "Channel created", "channel": { "id": 2, "merchant_id": 2, "team_id": 2, "type": "walmart", "nickname": "Walmart Store", "channel_account_id": "pending", "connection_status": "unauthorized", "marketplace": "us", "created_at": "2026-06-16T12:00:00.000000+00:00", "updated_at": "2026-06-16T12:00:00.000000+00:00" } } ``` ### Get the Walmart channel authorize URL Return the Walmart OAuth URL to redirect the merchant to in order to authorize the channel. This is the real "authorize" step of connecting a Walmart channel. **GET** `/channels/walmart/{channel}/authorize-url` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | walmart_callback_uri | string | No | The Walmart authorization endpoint to redirect to, as handed to us by the App Store-initiated connect flow. Must be an allow-listed Walmart host. | #### Expected Response Status: `200` A successful response returning the OAuth URL to redirect to Content-Type: `application/json` ```json { "url": "https://login.account.wal-mart.com/authorize?responseType=code&clientId=abc&state=xyz" } ``` ### Index a Walmart channel's feeds The feeds submitted to Walmart for this channel, newest first, with their processing status. **GET** `/channels/walmart/{channel}/feeds` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | feed_type | string | No | Only feeds of this type | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A paginated list of feeds Content-Type: `application/json` ```json { "data": [ { "uuid": "019b2286-9fee-71de-9f64-154824d3aa4d", "feed_type": "MP_ITEM_MATCH", "status": "processed", "walmart_feed_id": "F129C19240844B97A3C6AD8F1A2C4997@AU8BAQA", "items_received": 1, "items_succeeded": 1, "items_failed": 0, "items_processing": 0, "errors": [], "submitted_at": "2026-09-28T15:00:05Z", "processed_at": "2026-09-28T15:04:40Z", "failed_at": null, "created_at": "2026-09-28T15:00:00Z" } ], "total": 1, "current_page": 1, "last_page": 1, "per_page": 10, "from": 1, "to": 1 } ``` ### Index a Walmart channel's listing inventory levels One entry per listing of the channel, with the last WFS and ship-node levels stored for it. Listings with no stored level are included with `wfs: null` and an empty `ship_nodes`; missing levels are not zero. Every quantity Walmart did not report is null, and zero is only returned when Walmart reported zero. WFS and ship-node levels are synced from separate Walmart requests, so each carries its own `synced_at` (the time of that request) and they can be of different ages. Levels are retained until a later sync replaces them, so an old `synced_at` means the level may no longer be current; the levels are not a guarantee of current stock or a complete catalogue. WFS and ship-node quantities may describe the same units and must not be added together. Nothing is fetched from Walmart by this request. Reads may lag recent writes slightly. Inactive channels remain readable. **GET** `/channels/walmart/{channel}/inventory-levels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | q | string | No | Search language filter. Supported fields: `listing_id` (integer; `:`, `!:`, `>`, `>=`, `<`, `<=`) and `sku` (string; `:`, `!:`, `~`, `!~`). Substring matches require at least 3 characters. Clauses can be combined with `AND` / `OR`. Any other field or operator is rejected with a 422. Example: `sku~"WIDGET" AND listing_id>"100"` | | sorts | array | No | Sort the results. Defaults to `listing_id` ascending; unless `listing_id` is sorted explicitly, `listing_id` ascending is applied last so listings with the same SKU keep a stable order. Example: `sorts[0][field]=sku&sorts[0][direction]=desc&sorts[0][order]=1` | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of listings per page | #### Expected Response Status: `200` A paginated list of the channel's listings with their stored inventory levels; `total` counts listings, not ship nodes Content-Type: `application/json` ```json { "data": [ { "listing_id": 21, "sku": "SD-AB-12345", "wfs": { "available_units": 120, "reserved_units": 4, "inbound_units": 0, "on_hand_units": 130, "unavailable_units": 6, "stock_status": "IN_STOCK", "synced_at": "2026-10-07T04:05:12Z" }, "ship_nodes": [ { "ship_node": "0701234567", "available_to_sell_quantity": 15, "input_quantity": 18, "reserved_quantity": null, "synced_at": "2026-10-07T04:06:40Z" } ] }, { "listing_id": 22, "sku": "SD-AB-67890", "wfs": null, "ship_nodes": [] } ], "total": 2, "current_page": 1, "last_page": 1, "per_page": 10, "from": 1, "to": 2 } ``` ### Refresh a Walmart listing's stored inventory levels Requires listings:update. Fetches fresh WFS inventory and inventory across all ship nodes for the listing's Walmart SKU (channel_identifier), then saves the reported levels together and returns the stored values. Both Walmart lookups must succeed before either source is saved. An inactive or disconnected channel is rejected. Quantities Walmart omits remain null; zero is stored only when Walmart reports zero. Previously stored WFS or ship-node levels omitted from a successful response are retained with their original synced_at. Newer stored observations are not overwritten. Each source carries the time its lookup began. WFS and ship-node quantities may describe the same units and must not be added together. The response is read from the primary database. **POST** `/channels/walmart/{channel}/inventory-levels/{listing}/refresh` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | listing | integer | Yes | The ID of a listing belonging to this channel | #### Expected Response Status: `200` The listing with its stored WFS and ship-node levels after the refresh Content-Type: `application/json` ```json { "data": { "listing_id": 21, "sku": "SD-AB-12345", "wfs": { "available_units": 120, "reserved_units": 4, "inbound_units": 48, "on_hand_units": 130, "unavailable_units": 6, "stock_status": "IN_STOCK", "synced_at": "2026-10-07T04:05:12Z" }, "ship_nodes": [ { "ship_node": "0701234567", "available_to_sell_quantity": 15, "input_quantity": 18, "reserved_quantity": 3, "synced_at": "2026-10-07T04:06:40Z" } ] } } ``` ### Refresh a Walmart listing's stored seller price Requires listings:update. Fetches the item for the listing's Walmart SKU (channel_identifier) and saves its reported price and item facts. Returns the stored price from the primary database. The price is the seller's own offer price. An inactive or disconnected channel is rejected. Empty responses and missing or unparseable prices retain the previous observation, including synced_at; without stored details, price and synced_at are null. Zero is stored only when Walmart reports zero. Newer stored details are not overwritten. synced_at is the time the lookup began. Catalogue links and WFS enrolment are preserved. **POST** `/channels/walmart/{channel}/listings/{listing}/price/refresh` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | listing | integer | Yes | The ID of a listing belonging to this channel | #### Expected Response Status: `200` The listing's stored price after the refresh Content-Type: `application/json` ```json { "data": { "listing_id": 1, "sku": "string", "price": { "amount": "string", "currency": "string" }, "synced_at": "2026-01-01T00:00:00Z" } } ``` ### List Walmart product types Walmart's product type taxonomy for a feed type, flattened to one row per product type, for a product type picker. Read from Walmart's `GET /v3/items/taxonomy` (https://developer.walmart.com/us-marketplace/reference/gettaxonomyresponse) and cached for 24 hours per marketplace and feed type. For an existing Walmart item, the product type it is listed under is authoritative; see `walmart.live_item.product_type` on the listing. **GET** `/channels/walmart/{channel}/taxonomy` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | feed_type | string | Yes | The item spec feed type whose taxonomy to return | #### Expected Response Status: `200` The product types Content-Type: `application/json` ```json { "data": [ { "category": "Beauty", "product_type_group": "Fragrances", "product_type": "Body Sprays" } ] } ``` ### Show a Walmart feed One feed with Walmart's result for each item in it. Items are empty until the feed is processed. **GET** `/channels/walmart/feeds/{walmart_feed}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | walmart_feed | string | Yes | The feed's uuid | #### Expected Response Status: `200` The feed and its items Content-Type: `application/json` ```json { "data": { "uuid": "019b2286-9fee-71de-9f64-154824d3aa4d", "feed_type": "MP_ITEM_MATCH", "status": "processed", "walmart_feed_id": "F129C19240844B97A3C6AD8F1A2C4997@AU8BAQA", "items_received": 1, "items_succeeded": 1, "items_failed": 0, "items_processing": 0, "errors": [], "submitted_at": "2026-09-28T15:00:05Z", "processed_at": "2026-09-28T15:04:40Z", "failed_at": null, "created_at": "2026-09-28T15:00:00Z", "items": [ { "sku": "ABC-123", "listing_id": 1, "wpid": "1YKTCEME6DEH", "ingestion_status": "SUCCESS", "errors": [] } ] } } ``` ### Show a Walmart catalog item's landed-price analytics Summarises daily UTC landed-price observations of the Walmart buy box for one Walmart catalog item into calendar buckets over [start, end). Catalog prices are global per platform, so no listing, channel or merchant link is needed; the caller needs listings:view on the narrated account. A uuid that is not an existing Walmart catalog item returns 404. Days are UTC calendar days, weeks start on Monday and months on the first. Edge buckets are clipped to the range. Each observed currency is its own series; an item with no observations in the range returns an empty series array. Averages are per observation, not time-weighted, and the current UTC day may still gain observations. **GET** `/channels/walmart/catalog-items/{catalog_item_uuid}/prices` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | catalog_item_uuid | string | Yes | The Walmart catalog item's uuid | | start | string | Yes | First UTC day to include, as YYYY-MM-DD with a four-digit AD year from 0001 to 9999. | | end | string | Yes | UTC day after the last day to include, as YYYY-MM-DD with a four-digit AD year from 0001 to 9999. Must be after start, at most 731 days later. | | granularity | string | Yes | Bucket size: UTC calendar day, Monday-start week, or calendar month. | #### Expected Response Status: `200` Landed-price buckets per observed currency. Content-Type: `application/json` ```json { "start": "string", "end": "string", "granularity": "day", "timezone": "UTC", "series": [ { "currency": "USD", "buckets": [ { "start": "string", "end": "string", "lowest_landed_price": "string", "highest_landed_price": "string", "average_landed_price": "string", "observation_count": 1, "observed_days": 1 } ] } ] } ``` ### Set up a listing on Walmart Set up the listing's SKU as an offer on an item already in Walmart's catalogue ("setup by match", the `MP_ITEM_MATCH` feed). Walmart processes the feed asynchronously: the listing is marked submitted, and the returned feed reports the outcome through the Walmart feeds endpoints. When the feed finishes, the listing becomes synced (with its WPID) or unsynced. **POST** `/channels/walmart/listings/{listing}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | | gtin | string | Yes | The GTIN, UPC or EAN of the Walmart catalogue item to match (8, 12, 13 or 14 digits) | | price | number | Yes | The offer price, in the channel's marketplace currency | | shipping_weight_lb | number | No | The shipping weight in pounds. Defaults to the listing's weight; required when the listing has none. | | condition | string | No | The item condition. Defaults to `New`. | #### Expected Response Status: `202` The feed was requested Content-Type: `application/json` ```json { "data": { "uuid": "019b2286-9fee-71de-9f64-154824d3aa4d", "feed_type": "MP_ITEM_MATCH", "status": "requested", "walmart_feed_id": null, "items_received": null, "items_succeeded": null, "items_failed": null, "items_processing": null, "errors": [], "submitted_at": null, "processed_at": null, "failed_at": null, "created_at": "2026-09-28T15:00:00Z" } } ``` ### Update listing attributes on Walmart Requests partial product content and offer attribute updates for an existing United States Walmart listing through an MP_MAINTENANCE feed. Include only attributes to update, using Walmart attribute names inside orderable and visible. The listing SKU is supplied automatically; gtin defaults to the linked catalogue item. Walmart validates category-specific attributes asynchronously. The returned feed tracks submission and item-level errors. The local listing status and content are not changed by this request. WFS trade item and supply chain fields require WFS item setup instead. For dedicated SKU-based price and MSRP updates without a GTIN, use PATCH /channels/walmart/listings/{listing}/price, which submits PRICE_AND_PROMOTION. **PATCH** `/channels/walmart/listings/{listing}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | | gtin | string | No | GTIN, UPC or EAN (8, 12, 13 or 14 digits). Defaults to the linked Walmart catalogue GTIN. Required when the listing has no catalogue GTIN. For restored or GTIN-exempt items, use the identifier Walmart assigned to the existing item. | | product_type | string | No | The Walmart product type that keys visible. Defaults to the product type Walmart lists the item under; when supplied it must equal that product type. Ignored without visible. | | visible | object | No | Product content attributes for the item's product type, using Walmart names (for example productName, shortDescription, mainImageUrl, productSecondaryImageURL, keyFeatures and category attributes). condition cannot be changed: it may only restate the live item's condition (`walmart.live_item.condition`), otherwise 422, and only for a product type whose spec has a condition attribute (many have none, such as Battle Ropes and Baby Blankets, and then any condition is refused as an attribute the product type does not have). Must meet Walmart's item spec for the product type: carry every attribute in `required` from GET /channels/walmart/listings/{listing}/content-requirements, plus any the spec requires for another attribute's value (for example warrantyText when has_written_warranty is "Yes - Warranty Text"), with each value meeting its spec rules (type, length, allowed values, item counts); no feed is sent otherwise. | | orderable | object | No | Offer attributes using Walmart names (for example price, ShippingWeight, startDate, endDate and stateRestrictions). sku, productIdentifiers, specProductType, condition, skuUpdate and productIdUpdate are reserved and must be omitted. Use the dedicated /price endpoint for pricing-only updates. | #### Expected Response Status: `202` The feed was requested Content-Type: `application/json` ```json { "data": { "uuid": "019b2286-9fee-71de-9f64-154824d3aa4d", "feed_type": "MP_MAINTENANCE", "status": "requested", "walmart_feed_id": null, "items_received": null, "items_succeeded": null, "items_failed": null, "items_processing": null, "errors": [], "submitted_at": null, "processed_at": null, "failed_at": null, "created_at": "2026-09-28T15:00:00Z" } } ``` ### Update a Walmart listing price and MSRP Queues a PRICE_AND_PROMOTION feed for an existing listing on a connected United States Walmart channel. Requires ListingsUpdate permission and the listing must belong to the current merchant and service provider context. The listing SKU is supplied automatically; no GTIN, catalogue link or product type is required. Supply a price and optionally msrp. Uses Walmart pricing specification 2.0.20240126-12_25_52-api with MPItem[].Promo&Discount. A 202 response means queued, not applied: monitor GET /channels/walmart/feeds/{walmart_feed} for submission and item-level ingestion errors. Filter channel feeds with feed_type=PRICE_AND_PROMOTION. The local listing status and content are unchanged. Promotion creation and deletion are not supported by this endpoint. Walmart reference: https://developer.walmart.com/us-marketplace/docs/update-bulk-prices. **PATCH** `/channels/walmart/listings/{listing}/price` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | | price | number | Yes | Selling price in USD, greater than zero, with at most two decimal places. Numeric strings are accepted and sent to Walmart as numbers. | | msrp | number | No | Optional MSRP in USD, non-negative, with at most two decimal places. Omit to leave it unchanged; null is not accepted. Numeric strings are accepted and sent to Walmart as numbers. | #### Expected Response Status: `202` The pricing feed was queued. Monitor its status and item-level ingestion errors using the feed endpoints. Content-Type: `application/json` ```json { "data": { "uuid": "019b2286-9fee-71de-9f64-154824d3aa4d", "feed_type": "PRICE_AND_PROMOTION", "status": "requested", "walmart_feed_id": null, "items_received": null, "items_succeeded": null, "items_failed": null, "items_processing": null, "errors": [], "submitted_at": null, "processed_at": null, "failed_at": null, "created_at": "2026-09-28T15:00:00Z" } } ``` ### Show the content requirements of a Walmart listing The content (`Visible`) attributes Walmart's item spec defines for the product type Walmart lists the item under, for building a content form. `required` is every attribute a content change must carry: the spec's unconditional `required` list (`spec_required`) united with Walmart's content standards (`content_standards`: `productName`, `shortDescription`, `mainImageUrl`, `keyFeatures`, kept only where the product type has them). The live `MP_MAINTENANCE` spec marks none of the content standards required (for many product types it has no unconditional `required` list at all), yet Walmart's ingestion refuses a content change without them (`EXT_DATA_ERROR_05045574625354`; https://public.walmart.com/content/ContentStandards/en_us/importance-of-content-standards.html), so they come from that ingestion evidence rather than the spec. `conditional` lists the spec's `allOf` `if`/`then` rules as the attribute that triggers them (`when`) and the attributes they then require (`then`); it is listed as Walmart gives it and not evaluated here, and the value that triggers a rule (e.g. which `has_written_warranty` answer calls for `warrantyText` rather than `warrantyURL`) is not included. A content change on `PATCH /channels/walmart/listings/{listing}` that misses a `required` attribute, misses one a `conditional` rule requires for the value sent, or has a value breaking its spec rules is refused with 422 before any feed is sent. Walmart may still refuse a content change on rules this check leaves to Walmart (such as value formats, or rules outside the spec); those come back as the feed's ingestion errors. Read from Walmart's `POST /v3/items/spec` (https://developer.walmart.com/us-marketplace/reference/getspec) for the `MP_MAINTENANCE` feed type at the version our maintenance feed is sent with, and cached for 24 hours per marketplace, feed type and product type. **GET** `/channels/walmart/listings/{listing}/content-requirements` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | #### Expected Response Status: `200` The content requirements Content-Type: `application/json` ```json { "data": { "product_type": "Battle Ropes", "required": [ "productName", "shortDescription", "mainImageUrl", "keyFeatures" ], "spec_required": [], "content_standards": [ "productName", "shortDescription", "mainImageUrl", "keyFeatures" ], "conditional": [ { "when": "has_written_warranty", "then": [ "warrantyText", "warrantyURL" ] } ], "optional": [ "brand", "productSecondaryImageURL" ] } } ``` ### Get current Walmart listing content Fetches fresh content directly from Walmart for a listing on a connected Walmart channel. Resolves the exact seller SKU with GET /v3/items/{sku}, then searches GET /v3/items/walmart/search using the live item ID, or its normalized GTIN/UPC when Walmart omits the item ID. Returns only an unambiguous matching catalog item, with a matching condition when both responses include one. No local catalog link is required. Requires ListingsView permission and the listing must belong to the current merchant and service provider context. This is a partial read of Walmart's published catalog, not a complete maintenance feed or saved draft. Unpublished items may not appear in catalog search. Missing text fields are null and missing images are an empty array; never use those missing values to overwrite a draft. Key features and category-specific attributes are not exposed by this endpoint, so use GET /channels/walmart/listings/{listing}/content-requirements to determine what else an update needs. For PATCH /channels/walmart/listings/{listing}, map title to visible.productName, description to visible.shortDescription and brand to visible.brand; image URLs can prefill visible.mainImageUrl and visible.productSecondaryImageURL after review. The response is not guaranteed to satisfy Walmart's maintenance requirements. Text and HTML are preserved as Walmart returns them. Walmart API reference: https://developer.walmart.com/us-marketplace/reference/getsearchresult. **GET** `/channels/walmart/listings/{listing}/content` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | #### Expected Response Status: `200` Current available Walmart catalog content Content-Type: `application/json` ```json { "data": { "listing_id": 1, "sku": "string", "item_id": "string", "gtin": "string", "product_type": "string", "title": "string", "description": "string", "brand": "string", "images": [ "string" ] } } ``` ### Show WFS conversion requirements Resolves the listing live by SKU on its connected US Walmart channel and returns the OMNI_WFS conversion JSON schemas at 5.0.20260803-17_50_56-api, also used by conversion validation and feed generation. No local catalog link is needed. Each schema retains Walmart properties, required, additionalProperties, types, bounds, enums and full if/then/else conditions; clients must evaluate value conditions rather than treating every then field as unconditionally required. visible_schema applies inside Visible[product_type], orderable_schema to Orderable and trade_item_schema to TradeItem. feed_schema is the complete envelope restricted to the live product type. See the conversion endpoint for snake_case input mappings. These are conversion requirements, distinct from content-requirements (MP_MAINTENANCE). Requirements are cached for 24 hours by marketplace, OMNI_WFS, exact version and product type. **GET** `/channels/walmart/listings/{listing}/wfs-conversion-requirements` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | #### Expected Response Status: `200` The WFS conversion requirements for the live product type Content-Type: `application/json` ```json { "data": { "product_type": "Battle Ropes", "feed_type": "OMNI_WFS", "spec_version": "5.0.20260803-17_50_56-api" } } ``` ### Convert a Walmart listing to WFS Requests conversion of an existing United States Walmart Marketplace listing through an OMNI_WFS feed at specification 5.0.20260803-17_50_56-api. The live SKU lookup supplies the product type and GTIN/UPC; a local catalog link is not required. GET /channels/walmart/listings/{listing}/wfs-conversion-requirements returns the exact conversion schemas, including field placement, types, enums and value-dependent requirements. The content-requirements endpoint describes MP_MAINTENANCE and is not a conversion schema. The generated feed is validated before submission. A 202 means queued for asynchronous processing, not converted; monitor the returned feed for ingestion errors. **POST** `/channels/walmart/listings/{listing}/convert-to-wfs` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of a listing on a Walmart channel | | product_type | string | No | The Walmart product type used as the key in the feed's Visible block. Defaults to the product type Walmart lists the item under; when supplied it must equal that product type. | | price | number | Yes | The item price in the Walmart channel's marketplace currency | | country_of_origin_assembly | array | Yes | | | battery_technology_type | string | Yes | | | electronics_indicator | boolean | Yes | | | chemical_aerosol_pesticide | boolean | No | Legacy compatibility: false supplies No for any omitted is_chemical/is_aerosol/is_pesticide flags. True is rejected because it cannot identify which hazard applies; supply the three explicit flags. | | state_restrictions_text | string | No | Walmart's state restriction value. Defaults to `None`. | | each | object | Yes | | | each.width_in | number | Yes | | | each.height_in | number | Yes | | | each.depth_in | number | Yes | | | each.weight_lb | number | Yes | | | visible | object | Yes | Attributes placed exactly in SupplierItem[0].Visible[live product type]. Must meet visible_schema from the WFS requirements endpoint. No maintenance content standards are added. Unknown fields are rejected, never stripped. For Battle Ropes this release requires productName, brand, isProp65WarningRequired, mainImageUrl, netContent and condition (New). isProp65WarningRequired=Yes requires prop65WarningText. | | end_date | string | Yes | Future UTC date, mapped to Orderable.endDate at midnight. | | inner_pack | null | No | Only null or omission is accepted. This conversion version does not support TradeItem.innerPack. | | is_chemical | boolean | No | Maps to Orderable.isChemical as Yes/No. Yes triggers the conditional compliance requirements in orderable_schema. | | is_aerosol | boolean | No | Maps to Orderable.isAerosol as Yes/No. Yes triggers the conditional compliance requirements in orderable_schema. | | is_pesticide | boolean | No | Maps to Orderable.isPesticide as Yes/No. Yes triggers the conditional compliance requirements in orderable_schema. | | orderable | object | No | Additional attributes placed in SupplierItem[0].Orderable, preserving Walmart field names and JSON types. Must meet orderable_schema, including conditional requirements for hazards and batteries: labelImage, safetyDataSheet, numberOfHazardousComponents, hasBatteries, batterySize, lithiumIonBatteries, lithiumMetalBatteries, required_storage_condition and pesticide_type when applicable. sku, productIdentifiers, price, stateRestrictions, electronicsIndicator, batteryTechnologyType, isChemical, isAerosol, isPesticide and endDate are managed by the listing or top-level request fields and cannot be supplied here. Unsupported attributes are rejected. | #### Expected Response Status: `202` The WFS conversion feed was requested Content-Type: `application/json` ```json { "data": { "uuid": "019b2286-9fee-71de-9f64-154824d3aa4d", "feed_type": "MP_ITEM_MATCH", "status": "processed", "walmart_feed_id": "F129C19240844B97A3C6AD8F1A2C4997@AU8BAQA", "items_received": 1, "items_succeeded": 1, "items_failed": 0, "items_processing": 0, "errors": [ { "code": "string", "message": "string" } ], "submitted_at": "2026-01-01T00:00:00Z", "processed_at": "2026-01-01T00:00:00Z", "failed_at": "2026-01-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z" } } ``` ### Index a Walmart channel's WFS inbound orders The channel's Walmart Fulfillment Services inbound orders, newest first. **GET** `/channels/walmart/{channel}/wfs/inbound-orders` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | status | string | No | Only orders with this status | | search | string | No | Only orders whose `inbound_order_id` contains this text, case-insensitively | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page. Defaults to 10. | #### Expected Response Status: `200` A paginated list of inbound orders Content-Type: `application/json` ```json { "data": [ { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-09-29T14:02:11Z", "rejected_at": null, "cancellation_requested_at": null, "last_reconciled_at": "2026-09-29T15:00:03Z", "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T15:00:03Z" }, { "uuid": "019b2c3e-12aa-80ee-8c07-5f1e2d3c4b5a", "inbound_order_id": "PO-2026-0041", "channel_id": 1024, "merchant_id": 1042, "status": "rejected", "item_count": 2, "unit_count": 48, "shipment_ids": [], "errors": [ { "code": "ERR_EXT_DATA_0801001", "field": "items[1].itemQty", "description": "Item quantity is invalid." } ], "consecutive_failure_count": 0, "submitted_at": null, "rejected_at": "2026-09-29T12:40:10Z", "cancellation_requested_at": null, "last_reconciled_at": null, "created_at": "2026-09-29T12:31:02Z", "updated_at": "2026-09-29T12:40:10Z" } ], "total": 2, "current_page": 1, "last_page": 1, "per_page": 10, "from": 1, "to": 2 } ``` ### Draft a WFS inbound order Create a draft inbound order on a Walmart channel with its return address and items. Nothing is sent to Walmart until the order is submitted. **POST** `/channels/walmart/{channel}/wfs/inbound-orders` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | inbound_order_id | string | Yes | Your id for the order. Must be unique on the channel. | | return_address | object | Yes | Where Walmart returns inventory it cannot receive | | return_address.address_line_1 | string | Yes | | | return_address.address_line_2 | string | No | | | return_address.city | string | Yes | | | return_address.state_code | string | Yes | | | return_address.country_code | string | Yes | ISO 3166-1 alpha-2 country code, exactly 2 characters | | return_address.postal_code | string | Yes | | | inventory_transfer_service | boolean | No | Use Walmart's Inventory Transfer Service, sent as `inboundServices.inventoryTransferService: Y`. Omitted or false is self-distribution, Walmart's default, and nothing is sent. | | items | array | Yes | The SKUs to send, each at most once | | items.*.sku | string | Yes | Must be unique within the order (compared case-sensitively) | | items.*.gtin | string | Yes | The item's GTIN, UPC or EAN: 8, 12, 13 or 14 digits; the check digit is not validated | | items.*.item_description | string | Yes | | | items.*.item_qty | integer | Yes | The total units of the SKU. With case packs it must equal `vendor_pack_qty` times `inner_pack_qty`. | | items.*.vendor_pack_qty | integer | No | The number of cases. Send together with `inner_pack_qty` for case-packed items; omit both for loose units. | | items.*.inner_pack_qty | integer | No | The units per case. Send together with `vendor_pack_qty`. | | items.*.expected_delivery_date | string | Yes | When the item is expected at Walmart, as `YYYY-MM-DD` | | items.*.item_labeling | boolean | No | Ask WFS to label the units (the Item Labeling prep service). Defaults to false. | #### Expected Response Status: `201` The draft order Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "draft", "item_count": 1, "unit_count": 120, "shipment_ids": [], "errors": [], "consecutive_failure_count": 0, "submitted_at": null, "rejected_at": null, "cancellation_requested_at": null, "last_reconciled_at": null, "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T13:58:40Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [], "timeline": [ { "event_uuid": "019b2c41-7b1d-8010-a3f2-6c1d0e9b8a70", "event_type": "item_added", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T13:58:40Z" }, { "event_uuid": "019b2c41-7b1c-8010-9f11-2b3c4d5e6f70", "event_type": "drafted", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T13:58:40Z" } ] } } ``` ### Search a GTIN's WFS hazmat compliance holds Asks Walmart whether an item is on a WFS hazmat compliance hold. `in_review` clears within about 72 business hours; `action_needed` means the item data must be fixed and converted to WFS again; `prohibited` means the item cannot be sold through WFS. An item with several errors is one row per error. Nothing is stored. Walmart: https://developer.walmart.com/us-marketplace/reference/wercsfeedback **GET** `/channels/walmart/{channel}/wfs/holds` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Walmart channel | | gtin | string | Yes | The item's GTIN, UPC or EAN: 8, 12, 13 or 14 digits | #### Expected Response Status: `200` The holds, newest first; empty when the item is not on hold Content-Type: `application/json` ```json { "data": [ { "gtin": "00051494401255", "sku": "SD-AB-12345", "status": "action_needed", "field": "batteryTechnologyType", "description": "This item may contain a lithium or lead acid battery that requires additional compliance information, check the 'Battery Type' field.", "updated_at": "2021-08-26T15:48:44Z" } ] } ``` ### Show a WFS inbound order One inbound order with its items, its shipments (with their items and carrier bookings) and its timeline. **GET** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | #### Expected Response Status: `200` The inbound order Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-09-29T14:02:11Z", "rejected_at": null, "cancellation_requested_at": null, "last_reconciled_at": "2026-09-29T15:00:03Z", "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T15:00:03Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "1 Walmart Way", "address_line_2": null, "city": "Dallas", "state_code": "TX", "country_code": "US", "postal_code": "75201" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": null, "actual_delivery_date": null, "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": null, "tracking_numbers": [], "allocated_at": "2026-09-29T14:02:11Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": { "quote_type": "LTL", "quote_id": "Q-1", "carrier_id": "C-9", "carrier_name": "Acme Freight", "currency": "USD", "net_charge_cents": 18950, "state": "live", "terms_accepted_at": "2026-09-29T14:30:00Z", "booked_at": "2026-09-29T14:30:02Z", "cancel_by": "2026-09-29T15:30:02Z", "cancelled_at": null, "invalidated_at": null, "ship_date": "2026-10-01T00:00:00Z", "label_generated_at": null, "pickup": { "confirmation_number": "PU-77", "date": "2026-10-01", "ready_time": "09:00", "close_time": "17:00", "status": "SCHEDULED" } } } ], "timeline": [ { "event_uuid": "019b2c4a-1f01-8010-a3f2-6c1d0e9b8a70", "event_type": "pickup_observed", "user_uuid": null, "shipment_id": "SHP-8812", "details": null, "occurred_at": "2026-09-29T14:31:00Z" }, { "event_uuid": "019b2c4a-1e01-8010-a3f2-6c1d0e9b8a70", "event_type": "carrier_booked", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": "SHP-8812", "details": null, "occurred_at": "2026-09-29T14:30:02Z" }, { "event_uuid": "019b2c4a-1d01-8010-a3f2-6c1d0e9b8a70", "event_type": "submitted", "user_uuid": null, "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:02:11Z" }, { "event_uuid": "019b2c4a-1c01-8010-a3f2-6c1d0e9b8a70", "event_type": "item_added", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T13:58:40Z" }, { "event_uuid": "019b2c4a-1b01-8010-a3f2-6c1d0e9b8a70", "event_type": "drafted", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T13:58:40Z" } ] } } ``` ### Replace the items of a WFS inbound order Replace the item set of a draft or rejected inbound order before it is submitted again. A rejected order keeps its `inbound_order_id`: Walmart expects the corrected order to be resubmitted under the same id. Nothing is sent to Walmart until the order is submitted. **PUT** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | items | array | Yes | The order's complete item set, each SKU at most once. SKUs on the order but not in the list are removed, new SKUs are added, and a SKU whose fields changed is replaced; an unchanged SKU records nothing. | | items.*.sku | string | Yes | Must be unique within the order (compared case-sensitively) | | items.*.gtin | string | Yes | The item's GTIN, UPC or EAN: 8, 12, 13 or 14 digits; the check digit is not validated | | items.*.item_description | string | Yes | | | items.*.item_qty | integer | Yes | The total units of the SKU. With case packs it must equal `vendor_pack_qty` times `inner_pack_qty`. | | items.*.vendor_pack_qty | integer | No | The number of cases. Send together with `inner_pack_qty` for case-packed items; omit both for loose units. | | items.*.inner_pack_qty | integer | No | The units per case. Send together with `vendor_pack_qty`. | | items.*.expected_delivery_date | string | Yes | When the item is expected at Walmart, as `YYYY-MM-DD` | | items.*.item_labeling | boolean | No | Ask WFS to label the units (the Item Labeling prep service). Omit to keep the saved choice of an item already on the order; a new item defaults to false. | | inventory_transfer_service | boolean | No | Use Walmart's Inventory Transfer Service, sent as `inboundServices.inventoryTransferService: Y`. Omitted or false is self-distribution, Walmart's default, and nothing is sent. Omitted leaves the order's choice unchanged. | #### Expected Response Status: `200` The inbound order with its new items Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "rejected", "item_count": 1, "unit_count": 120, "shipment_ids": [], "errors": [ { "code": "ERR_EXT_DATA_0801001", "field": "items[0].itemQty", "description": "Item quantity is invalid." } ], "consecutive_failure_count": 0, "submitted_at": null, "rejected_at": "2026-09-29T14:02:11Z", "cancellation_requested_at": null, "last_reconciled_at": null, "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T14:30:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [], "timeline": [ { "event_uuid": "019b2c4a-3a01-8010-a3f2-6c1d0e9b8a70", "event_type": "item_added", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:30:00Z" }, { "event_uuid": "019b2c4a-2a01-8010-a3f2-6c1d0e9b8a70", "event_type": "item_removed", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:30:00Z" }, { "event_uuid": "019b2c4a-1d01-8010-a3f2-6c1d0e9b8a70", "event_type": "rejected", "user_uuid": null, "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:02:11Z" } ] } } ``` ### Preview the destinations and ITS fees of a WFS inbound order Asks Walmart where the order's units would go, both with Inventory Transfer Service (ITS) and with self-distribution, and what ITS would cost. Walmart's figures are estimates: routing and fees are fixed when the order is submitted. Only Draft and Rejected orders can be previewed. Nothing is stored except a `preview_fetched` timeline entry. Walmart: https://developer.walmart.com/us-marketplace/reference/inboundpreview **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/preview` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | item_labeling_skus | array | No | The SKUs to preview with the Item Labeling prep service, replacing the items' own choice for this preview only. Omit to use the items' own choice. | #### Expected Response Status: `200` Walmart's preview Content-Type: `application/json` ```json { "data": { "destinations": [ { "type": "wfs", "walmart_type": "wfs", "ship_node": "8240", "node_type": "FC", "is_sortable": true, "is_non_sortable": false, "ship_to_address": { "fc_name": "ATL1", "address_line_1": "6055 S Fulton Pkwy", "address_line_2": null, "city": "Atlanta", "state_code": "GA", "country_code": "US", "postal_code": "30349" }, "units": 1, "items": [ { "sku": "CHH2609", "gtin": "00704551260905", "item_qty": 1 } ] } ], "its_fees": [] } } ``` ### Submit a WFS inbound order to Walmart Queue a draft or rejected inbound order for submission to Walmart. Submission happens in the background, so the returned order is still in its previous status (`draft` or `rejected`); poll the order to see it become `submitted` (with its shipments) or `rejected` (with `errors`). Submitting again while a submission is queued queues nothing more. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/submit` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | #### Expected Response Status: `202` The submission was queued Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "draft", "item_count": 1, "unit_count": 120, "shipment_ids": [], "errors": [], "consecutive_failure_count": 0, "submitted_at": null, "rejected_at": null, "cancellation_requested_at": null, "last_reconciled_at": null, "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T13:58:40Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [], "timeline": [ { "event_uuid": "019b2c4a-1c01-8010-a3f2-6c1d0e9b8a70", "event_type": "item_added", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T13:58:40Z" }, { "event_uuid": "019b2c4a-1b01-8010-a3f2-6c1d0e9b8a70", "event_type": "drafted", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T13:58:40Z" } ] } } ``` ### Request cancellation of a WFS inbound order Ask Walmart to cancel a submitted inbound order. Walmart's answer is recorded on the order rather than returned as an error: `timeline[0].event_type` is `cancellation_requested` when Walmart accepted (and `cancellation_requested_at` is set), `cancellation_rejected` when it refused, or `api_error_occurred` when the call failed (see `errors`). The order becomes `cancelled` once Walmart reports it cancelled. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/cancellation-request` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | #### Expected Response Status: `200` The inbound order, with the outcome on its timeline Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-09-29T14:02:11Z", "rejected_at": null, "cancellation_requested_at": "2026-09-29T16:10:00Z", "last_reconciled_at": "2026-09-29T15:00:03Z", "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T16:10:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "1 Walmart Way", "address_line_2": null, "city": "Dallas", "state_code": "TX", "country_code": "US", "postal_code": "75201" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": null, "actual_delivery_date": null, "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": null, "tracking_numbers": [], "allocated_at": "2026-09-29T14:02:11Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": null } ], "timeline": [ { "event_uuid": "019b2c4a-2a01-8010-a3f2-6c1d0e9b8a70", "event_type": "cancellation_requested", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": null, "details": null, "occurred_at": "2026-09-29T16:10:00Z" }, { "event_uuid": "019b2c4a-1d01-8010-a3f2-6c1d0e9b8a70", "event_type": "submitted", "user_uuid": null, "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:02:11Z" } ] } } ``` ### Update a WFS shipment's quantities Change how many units of each SKU a shipment will carry. Walmart allows an increase of at most six units per SKU after submission, and a SKU is removed by setting it to 0, but not every SKU on the shipment (that would cancel the whole inbound order); a request outside those rules is refused with 422 before Walmart is called (Walmart remains the authority and may still refuse). The outcome is recorded on the order: `timeline[0].event_type` is `shipment_quantities_updated` when Walmart accepted, `shipment_quantities_rejected` when it refused (also answered 422), or `shipment_quantities_update_unconfirmed` when the call failed (answered 200; the outcome will be learned when the shipment is next refreshed). **PUT** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/quantities` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | quantities | object | Yes | The new unit quantity for each SKU to change, keyed by SKU. Every SKU must already be on the shipment. Each quantity is 0 (removes the SKU) or between 1 and the SKU's current `requested_qty` plus 6. At least one SKU on the shipment must stay above 0. | #### Expected Response Status: `200` The inbound order, with the outcome on its timeline Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-09-29T14:02:11Z", "rejected_at": null, "cancellation_requested_at": null, "last_reconciled_at": "2026-09-29T15:00:03Z", "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T16:20:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "1 Walmart Way", "address_line_2": null, "city": "Dallas", "state_code": "TX", "country_code": "US", "postal_code": "75201" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": null, "actual_delivery_date": null, "requested_units": 96, "received_units": 0, "damaged_units": 0, "carrier_name": null, "tracking_numbers": [], "allocated_at": "2026-09-29T14:02:11Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 96, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": null } ], "timeline": [ { "event_uuid": "019b2c4a-3a01-8010-a3f2-6c1d0e9b8a70", "event_type": "shipment_quantities_updated", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": "SHP-8812", "details": null, "occurred_at": "2026-09-29T16:20:00Z" }, { "event_uuid": "019b2c4a-1d01-8010-a3f2-6c1d0e9b8a70", "event_type": "submitted", "user_uuid": null, "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:02:11Z" } ] } } ``` ### Submit tracking for a WFS shipment Tell Walmart which carrier and tracking numbers a shipment is travelling with. The outcome is recorded on the order: `timeline[0].event_type` is `tracking_submitted` when Walmart accepted (and the shipment shows the carrier and tracking numbers), `tracking_rejected` when it refused, or `api_error_occurred` when the call failed. A Walmart refusal answers 422 and a call Walmart did not answer answers 502. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/tracking` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | carrier_name | string | Yes | | | tracking_numbers | array | Yes | Each number at most once | #### Expected Response Status: `200` The inbound order, with the outcome on its timeline Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-09-29T14:02:11Z", "rejected_at": null, "cancellation_requested_at": null, "last_reconciled_at": "2026-09-29T15:00:03Z", "created_at": "2026-09-29T13:58:40Z", "updated_at": "2026-09-29T16:30:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "1 Walmart Way", "address_line_2": null, "city": "Dallas", "state_code": "TX", "country_code": "US", "postal_code": "75201" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": null, "actual_delivery_date": null, "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": "UPS", "tracking_numbers": [ "1Z999AA10123456784", "1Z999AA10123456785" ], "allocated_at": "2026-09-29T14:02:11Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": null } ], "timeline": [ { "event_uuid": "019b2c4a-4a01-8010-a3f2-6c1d0e9b8a70", "event_type": "tracking_submitted", "user_uuid": "019a0f11-2c3d-8001-9e4f-5a6b7c8d9e0f", "shipment_id": "SHP-8812", "details": null, "occurred_at": "2026-09-29T16:30:00Z" }, { "event_uuid": "019b2c4a-1d01-8010-a3f2-6c1d0e9b8a70", "event_type": "submitted", "user_uuid": null, "shipment_id": null, "details": null, "occurred_at": "2026-09-29T14:02:11Z" } ] } } ``` ### Create a WFS shipment box label Have Walmart create the box labels for a shipment and download them. The file is returned as Walmart produced it and is not stored. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/box-label` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | label_size | string | No | The label size. Walmart's default when omitted. | | label_format | string | No | The file format. Walmart's default when omitted. | | load_types | array | No | How many labels to create for each kind of load | #### Expected Response Status: `200` The label file, with Walmart's `Content-Type` and `Content-Disposition: attachment; filename="wfs-box-label-."` Content-Type: `application/pdf` ```json "string" ``` ### List the rate quotes of a WFS shipment The Walmart preferred-carrier quotes requested for a shipment, newest first, at most 200. **GET** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/rate-quotes` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | #### Expected Response Status: `200` The shipment's quotes Content-Type: `application/json` ```json { "data": [ { "uuid": "019b2c52-3f10-7c4e-8a1d-2b3c4d5e6f70", "quote_type": "Parcel", "quote_id": "Q-7781", "carrier_id": "FEDEX", "carrier_name": "FedEx", "currency": "USD", "net_charge_cents": 1250, "total_charge_cents": 1500, "estimated_delivery_at": "2026-10-08T00:00:00Z", "expires_at": "2026-10-02T12:00:00Z", "quote_status": "ACTIVE", "requested_at": "2026-10-01T12:00:00Z", "selected_at": "2026-01-01T00:00:00Z" } ] } ``` ### Request rate quotes for a WFS shipment Ask Walmart's preferred-carrier programme for quotes. The fields besides `quote_type` and `ship_from` depend on the quote type. The returned quotes are kept and can be booked with the carrier booking endpoint. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/rate-quotes` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | quote_type | string | Yes | | | ship_from | object | Yes | The address the carrier collects from | | ship_from.address_line_1 | string | Yes | | | ship_from.address_line_2 | string | No | | | ship_from.city | string | Yes | | | ship_from.state_code | string | Yes | | | ship_from.country_code | string | Yes | | | ship_from.postal_code | string | Yes | | | ship_from.phone | string | No | | | ship_from.location_name | string | No | | | packages | array | No | The boxes to ship. Required for `Parcel`. | | pickup_from | string | No | Earliest pickup. Required for `LTL` and `FTL`. An ISO 8601 timestamp in UTC or with an offset, e.g. `2026-10-06T08:00:00Z` | | pickup_to | string | No | Latest pickup, after `pickup_from`. Required for `LTL` and `FTL`. | | freight | object | No | Freight details. Required for `LTL` and `FTL`. | | pallets | array | No | The pallets to ship. Required for `LTL` and `FTL`. | | equipment | array | No | The truck equipment. Required for `FTL`. | | mode | string | No | Required for `FTL` | | service_level | string | No | Required for `FTL` | #### Expected Response Status: `200` The quotes Walmart returned Content-Type: `application/json` ```json { "data": [ { "uuid": "019b2c52-3f10-7c4e-8a1d-2b3c4d5e6f70", "quote_type": "Parcel", "quote_id": "Q-7781", "carrier_id": "FEDEX", "carrier_name": "FedEx", "currency": "USD", "net_charge_cents": 1250, "total_charge_cents": 1500, "estimated_delivery_at": "2026-10-08T00:00:00Z", "expires_at": "2026-10-02T12:00:00Z", "quote_status": "ACTIVE", "requested_at": "2026-10-01T12:00:00Z", "selected_at": "2026-01-01T00:00:00Z" } ] } ``` ### Book a carrier for a WFS shipment Book one of the shipment's rate quotes. The quote's type decides which fields are required. Walmart's answer is recorded on the order: `timeline[0].event_type` is `carrier_booked`, `carrier_booking_rejected`, `carrier_booking_unconfirmed` or `api_error_occurred`. A Walmart refusal answers 422 and a call Walmart did not answer answers 502; an unconfirmed booking answers 200 with `carrier_booking.state` `unconfirmed`. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/carrier-booking` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | rate_quote_uuid | string | Yes | A quote of this shipment | | single_sku_boxes | integer | Yes | | | mixed_sku_boxes | integer | Yes | | | business_location_name | string | No | Required for `LTL` and `FTL` | | pickup_instruction | string | No | | | pickup_dates | array | No | Preferred pickup dates. Required for `LTL`. | | shipper | object | No | Who the carrier contacts at pickup. Required for `LTL` and `FTL`. | | ship_from | object | No | The address the carrier collects from. Required for `LTL` and `FTL`. | | operation_hours | array | No | The pickup location's opening hours by weekday. Walmart requires them for LTL and FTL bookings: at least three days, including every preferred pickup date (`pickup_dates`; for FTL, every day from `schedule.min_pickup_at` to `schedule.max_pickup_at`); a booking without them is refused with 'At least 3 days of operation hours must be provided, including the preferred pickup date.' Times as `HH:MM:SS`. | | declared_value | number | No | | | total_pallet_count | integer | No | Required for `LTL` | | pallets | array | No | The pallets. Required for `LTL` and `FTL`. | | pickup_window | string | No | Required for `FTL` | | schedule | object | No | The FTL pickup and delivery window. Required for `FTL`. | | equipment_code | string | No | Required for `FTL` | | equipment_type | string | No | Required for `FTL` | | equipment_length_ft | number | No | Required for `FTL` | | protection_level | string | No | Required for `FTL` | #### Expected Response Status: `200` The inbound order, with the outcome on its timeline and the booking on the shipment Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-01-01T00:00:00Z", "rejected_at": "2026-01-01T00:00:00Z", "cancellation_requested_at": "2026-01-01T00:00:00Z", "last_reconciled_at": "2026-01-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": "string", "actual_delivery_date": "string", "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": "UPS", "tracking_numbers": [ "1Z999AA10123456784" ], "allocated_at": "2026-01-01T00:00:00Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": { "quote_type": "LTL", "quote_id": "Q-1", "carrier_id": "C-9", "carrier_name": "Acme Freight", "currency": "USD", "net_charge_cents": 18950, "state": "live", "terms_accepted_at": "2026-01-01T00:00:00Z", "booked_at": "2026-01-01T00:00:00Z", "cancel_by": "2026-09-30T15:02:11Z", "cancelled_at": "2026-01-01T00:00:00Z", "invalidated_at": "2026-01-01T00:00:00Z", "ship_date": "2026-01-01T00:00:00Z", "label_generated_at": "2026-01-01T00:00:00Z", "pickup": { "confirmation_number": "PU-77", "date": "2026-10-01", "ready_time": "09:00", "close_time": "17:00", "status": "SCHEDULED" } } } ], "timeline": [ { "event_uuid": "string", "event_type": "submitted", "user_uuid": "string", "shipment_id": "SHP-8812", "occurred_at": "2026-01-01T00:00:00Z" } ] } } ``` ### Cancel the carrier booking of a WFS shipment Cancel the shipment's live booking. Walmart's answer is recorded on the order: `timeline[0].event_type` is `carrier_booking_cancelled`, `carrier_booking_cancellation_rejected` or `api_error_occurred`. A Walmart refusal answers 422 and a call Walmart did not answer answers 502. **DELETE** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/carrier-booking` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | #### Expected Response Status: `200` The inbound order, with the outcome on its timeline Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-01-01T00:00:00Z", "rejected_at": "2026-01-01T00:00:00Z", "cancellation_requested_at": "2026-01-01T00:00:00Z", "last_reconciled_at": "2026-01-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": "string", "actual_delivery_date": "string", "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": "UPS", "tracking_numbers": [ "1Z999AA10123456784" ], "allocated_at": "2026-01-01T00:00:00Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": { "quote_type": "LTL", "quote_id": "Q-1", "carrier_id": "C-9", "carrier_name": "Acme Freight", "currency": "USD", "net_charge_cents": 18950, "state": "live", "terms_accepted_at": "2026-01-01T00:00:00Z", "booked_at": "2026-01-01T00:00:00Z", "cancel_by": "2026-09-30T15:02:11Z", "cancelled_at": "2026-01-01T00:00:00Z", "invalidated_at": "2026-01-01T00:00:00Z", "ship_date": "2026-01-01T00:00:00Z", "label_generated_at": "2026-01-01T00:00:00Z", "pickup": { "confirmation_number": "PU-77", "date": "2026-10-01", "ready_time": "09:00", "close_time": "17:00", "status": "SCHEDULED" } } } ], "timeline": [ { "event_uuid": "string", "event_type": "submitted", "user_uuid": "string", "shipment_id": "SHP-8812", "occurred_at": "2026-01-01T00:00:00Z" } ] } } ``` ### Download the carrier label of a WFS shipment Download the carrier label of the shipment's live Parcel booking. The file is returned as Walmart produced it and is not stored. **GET** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/carrier-label` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | label_size | string | No | | #### Expected Response Status: `200` The label file, with Walmart's `Content-Type` Content-Type: `application/pdf` ```json "string" ``` ### Generate the carrier label of a WFS shipment Ask Walmart to generate the carrier label for a Parcel booking. Walmart generates it asynchronously; fetch it with `GET` on the same path. The outcome is recorded on the order: `timeline[0].event_type` is `carrier_label_generated`, `carrier_label_rejected` or `api_error_occurred`. A Walmart refusal answers 422 and a call Walmart did not answer answers 502. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/carrier-label` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | ship_date | string | No | When the parcels ship, as `YYYY-MM-DD` or an ISO 8601 timestamp | #### Expected Response Status: `202` The inbound order; `carrier_booking.label_generated_at` and `ship_date` show once Walmart accepted Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-01-01T00:00:00Z", "rejected_at": "2026-01-01T00:00:00Z", "cancellation_requested_at": "2026-01-01T00:00:00Z", "last_reconciled_at": "2026-01-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": "string", "actual_delivery_date": "string", "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": "UPS", "tracking_numbers": [ "1Z999AA10123456784" ], "allocated_at": "2026-01-01T00:00:00Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": { "quote_type": "LTL", "quote_id": "Q-1", "carrier_id": "C-9", "carrier_name": "Acme Freight", "currency": "USD", "net_charge_cents": 18950, "state": "live", "terms_accepted_at": "2026-01-01T00:00:00Z", "booked_at": "2026-01-01T00:00:00Z", "cancel_by": "2026-09-30T15:02:11Z", "cancelled_at": "2026-01-01T00:00:00Z", "invalidated_at": "2026-01-01T00:00:00Z", "ship_date": "2026-01-01T00:00:00Z", "label_generated_at": "2026-01-01T00:00:00Z", "pickup": { "confirmation_number": "PU-77", "date": "2026-10-01", "ready_time": "09:00", "close_time": "17:00", "status": "SCHEDULED" } } } ], "timeline": [ { "event_uuid": "string", "event_type": "submitted", "user_uuid": "string", "shipment_id": "SHP-8812", "occurred_at": "2026-01-01T00:00:00Z" } ] } } ``` ### Print the bill of lading of a WFS shipment Download the bill of lading of the shipment's live LTL booking. The file is returned as Walmart produced it and is not stored. **GET** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/bill-of-lading` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | #### Expected Response Status: `200` The bill of lading, with Walmart's `Content-Type` Content-Type: `application/pdf` ```json "string" ``` ### Read the carrier tracking of a WFS shipment Walmart's carrier tracking for the shipment's live booking, read in the booking's mode. Nothing is stored. **GET** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/carrier-tracking` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | #### Expected Response Status: `200` The tracking entries Content-Type: `application/json` ```json { "data": [ { "shipment_id": "SHP-8812", "tracking_no": "PRO-123", "status": "IN_TRANSIT", "carrier_name": "Old Dominion", "is_master": true, "current_location": "Dallas, TX", "estimated_delivery_at": "2026-10-08T17:00:00Z", "actual_delivery_at": "2026-01-01T00:00:00Z", "pro_number": "PRO-123", "event_at": "2026-10-06T12:30:00Z", "mode": "LTL", "event_time_zone": "CST" } ] } ``` ### Reschedule the pickup of a WFS shipment Ask Walmart to move the pickup of the shipment's live LTL booking. The booked quote is used. The outcome is recorded on the order: `timeline[0].event_type` is `pickup_rescheduled`, `pickup_reschedule_rejected` or `api_error_occurred`. A Walmart refusal answers 422 and a call Walmart did not answer answers 502. **PUT** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/pickup` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | | pickup_dates | array | Yes | The requested pickup dates, in order of preference | | pickup_dates.*.date | string | Yes | `YYYY-MM-DD` | | pickup_dates.*.ready_time | string | Yes | `HH:MM:SS` | | pickup_dates.*.close_time | string | Yes | `HH:MM:SS` | | pickup_dates.*.priority | integer | No | Defaults to the date's position in the list, starting at 1 | | contact | object | Yes | Who the carrier contacts at pickup | | contact.first_name | string | Yes | | | contact.last_name | string | Yes | | | contact.email | string | Yes | | | contact.secondary_email | string | No | | | contact.area_code | string | No | | | contact.number | string | Yes | | | contact.extension | string | No | | | ship_from | object | No | A new pickup address, if it changed | | carrier | string | No | | #### Expected Response Status: `200` The inbound order; the pickup shows on `carrier_booking.pickup` Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-01-01T00:00:00Z", "rejected_at": "2026-01-01T00:00:00Z", "cancellation_requested_at": "2026-01-01T00:00:00Z", "last_reconciled_at": "2026-01-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": "string", "actual_delivery_date": "string", "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": "UPS", "tracking_numbers": [ "1Z999AA10123456784" ], "allocated_at": "2026-01-01T00:00:00Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": { "quote_type": "LTL", "quote_id": "Q-1", "carrier_id": "C-9", "carrier_name": "Acme Freight", "currency": "USD", "net_charge_cents": 18950, "state": "live", "terms_accepted_at": "2026-01-01T00:00:00Z", "booked_at": "2026-01-01T00:00:00Z", "cancel_by": "2026-09-30T15:02:11Z", "cancelled_at": "2026-01-01T00:00:00Z", "invalidated_at": "2026-01-01T00:00:00Z", "ship_date": "2026-01-01T00:00:00Z", "label_generated_at": "2026-01-01T00:00:00Z", "pickup": { "confirmation_number": "PU-77", "date": "2026-10-01", "ready_time": "09:00", "close_time": "17:00", "status": "SCHEDULED" } } } ], "timeline": [ { "event_uuid": "string", "event_type": "submitted", "user_uuid": "string", "shipment_id": "SHP-8812", "occurred_at": "2026-01-01T00:00:00Z" } ] } } ``` ### Refresh the pickup of a WFS shipment Read the pickup Walmart scheduled for the shipment's live LTL booking and record it on the order when it changed. **POST** `/channels/walmart/wfs/inbound-orders/{wfs_inbound_order}/shipments/{shipment}/pickup/refresh` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | wfs_inbound_order | string | Yes | The inbound order's uuid | | shipment | string | Yes | Walmart's id for a shipment on the order | #### Expected Response Status: `200` The inbound order; the pickup shows on `carrier_booking.pickup` Content-Type: `application/json` ```json { "data": { "uuid": "019b2c41-7b1c-80ee-9a51-4d2e8f6b1a90", "inbound_order_id": "PO-2026-0042", "channel_id": 1024, "merchant_id": 1042, "status": "submitted", "item_count": 1, "unit_count": 120, "shipment_ids": [ "SHP-8812" ], "errors": [], "consecutive_failure_count": 0, "submitted_at": "2026-01-01T00:00:00Z", "rejected_at": "2026-01-01T00:00:00Z", "cancellation_requested_at": "2026-01-01T00:00:00Z", "last_reconciled_at": "2026-01-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z", "return_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "inventory_transfer_service": false, "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "item_description": "Widget", "item_qty": 120, "vendor_pack_qty": 12, "inner_pack_qty": 10, "expected_delivery_date": "2026-10-15", "item_labeling": false } ], "shipments": [ { "shipment_id": "SHP-8812", "fc_name": "DFW5", "ship_to_address": { "address_line_1": "100 Main St", "address_line_2": null, "city": "Bentonville", "state_code": "AR", "country_code": "US", "postal_code": "72712" }, "status": "pending_shipment_details", "expected_delivery_date": "2026-10-15", "updated_expected_delivery_date": "string", "actual_delivery_date": "string", "requested_units": 120, "received_units": 0, "damaged_units": 0, "carrier_name": "UPS", "tracking_numbers": [ "1Z999AA10123456784" ], "allocated_at": "2026-01-01T00:00:00Z", "items": [ { "sku": "SKU-1", "gtin": "00012345678905", "requested_qty": 120, "received_qty": 0, "damaged_qty": 0 } ], "carrier_booking": { "quote_type": "LTL", "quote_id": "Q-1", "carrier_id": "C-9", "carrier_name": "Acme Freight", "currency": "USD", "net_charge_cents": 18950, "state": "live", "terms_accepted_at": "2026-01-01T00:00:00Z", "booked_at": "2026-01-01T00:00:00Z", "cancel_by": "2026-09-30T15:02:11Z", "cancelled_at": "2026-01-01T00:00:00Z", "invalidated_at": "2026-01-01T00:00:00Z", "ship_date": "2026-01-01T00:00:00Z", "label_generated_at": "2026-01-01T00:00:00Z", "pickup": { "confirmation_number": "PU-77", "date": "2026-10-01", "ready_time": "09:00", "close_time": "17:00", "status": "SCHEDULED" } } } ], "timeline": [ { "event_uuid": "string", "event_type": "submitted", "user_uuid": "string", "shipment_id": "SHP-8812", "occurred_at": "2026-01-01T00:00:00Z" } ] } } ``` --- ## Channel Listings Viewing and managing channels and listings ### List listings for a channel **GET** `/channels/{channel_id}/listings` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | Yes | The ID of the channel | #### Expected Response Status: `200` A successful response returning the paginated list of listings Content-Type: `application/json` ```json { "data": [ { "id": 21, "created_at": "2025-03-10T04:02:47Z", "updated_at": "2025-03-10T09:22:27Z", "channel_id": 1, "sku": "Digital-A-433828", "title": "Digital Alarm Clock", "condition": null, "condition_note": null, "channel_identifier": "Digital-A-433828", "length_mm": null, "width_mm": null, "height_mm": null, "weight_gm": null, "status": "synced", "flags": [], "identifiers": [ { "id": 61, "listing_id": 21, "identifier": "6619524668697", "type": "EAN" } ], "images": [], "seller_listing_details_updated_at": null, "catalog_details_updated_at": null, "product_link": { "id": 175, "created_at": "2025-03-12T07:11:44Z", "listing_id": 21, "product_id": 21, "product_uuid": "550e8400-e29b-41d4-a716-446655440000" }, "channel_type": "amazon", "amazon": { "fnsku": "X0012345", "catalog_item": null }, "walmart": null } ], "total": 2, "current_page": 1, "last_page": 1, "per_page": 20, "from": 1, "to": 2 } ``` ### Create a listing for a channel **POST** `/channels/{channel_id}/listings` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | Yes | The ID of the channel | | channel_identifier | string | Yes | The channel-specific identifier for the listing (e.g. ASIN for Amazon) | | item_id | integer | No | The ID of the inventory item to link to this listing. If omitted, the listing is created without a linked item. | | merchant_sku | string | No | The merchant SKU to use for this listing. If omitted, the item's SKU is used, falling back to the channel identifier when there is no linked item. | | condition | string | No | Accepted for compatibility and not stored. Walmart conditions are set when the listing is pushed to Walmart. | #### Expected Response Status: `201` A successful response returning the created listing Content-Type: `application/json` ```json { "data": { "id": 1485, "created_at": "2025-03-12T09:01:36Z", "updated_at": "2025-03-12T09:01:36Z", "channel_id": 1, "sku": "Rotating-M-949927", "title": "Rotating Makeup Organizer", "condition": null, "condition_note": null, "channel_identifier": "Rotating-M-9499272", "length_mm": null, "width_mm": null, "height_mm": null, "weight_gm": null, "status": "checking", "flags": [], "identifiers": [], "images": [], "seller_listing_details_updated_at": null, "catalog_details_updated_at": null, "product_link": null, "channel_type": "amazon", "amazon": { "fnsku": null, "catalog_item": null }, "walmart": null } } ``` ### Link a listing to a product **POST** `/channels/listings/{listing}/link` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | listing | integer | Yes | The ID of the listing | | item_id | integer | Yes | The ID of the inventory item to link to this listing | #### Expected Response Status: `200` A successful response indicating the listing was linked Content-Type: `application/json` ```json { "message": "Listing linked to item" } ``` --- ## Listing Restrictions Retrieve Amazon listing restrictions for a channel. ### Index stored listing restrictions **GET** `/channels/amazon/{channel}/listing-restrictions` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Amazon channel | | q | string | No | Search language filter. Supported fields: `asin`, `marketplace_id`, and `condition_type`. | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning a paginated list of stored listing restriction records Content-Type: `application/json` ```json { "data": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "channel_id": 1, "asin": "B00ZB18SIF", "marketplace_id": "ATVPDKIKX0DER", "condition_type": "new_new", "restrictions": [ { "marketplace_id": "ATVPDKIKX0DER", "condition_type": "new_new", "reasons": [ { "reason_code": "APPROVAL_REQUIRED", "message": "Approval is required to list this item.", "links": [ { "resource": "https://sellercentral.amazon.com/hz/approvalrequest/restrictions/approve", "verb": "GET", "title": "Request approval" } ] } ] } ] } ], "total": 1, "current_page": 1, "last_page": 1, "per_page": 10, "from": 1, "to": 1 } ``` ### Fetch listing restrictions from Amazon **GET** `/channels/amazon/{channel}/fetch-listing-restrictions` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel | integer | Yes | The ID of the Amazon channel | | asin | string | Yes | | | condition_type | string | Yes | | #### Expected Response Status: `200` A successful response returning the fetched listing restriction record Content-Type: `application/json` Body: no response body is defined by the spec. --- ## Billing View and manage billing for fulfillment services. ### List merchant receivables Returns receivables totals aggregated per merchant for the current service provider: open charges, draft invoices, and unpaid invoices, each as a count and a total amount. When a merchant is selected in the request context, only that merchant's totals are returned. **GET** `/billing/receivables` #### Expected Response Status: `200` A successful response returning the receivables totals for each merchant Content-Type: `application/json` ```json [ { "merchant_id": 6320, "open_charges_count": 3, "open_charges_amount": "521.000000", "draft_invoices_count": 0, "draft_invoices_amount": "0.000000", "unpaid_invoices_count": 0, "unpaid_invoices_amount": "0.000000", "billing_currency": "USD" }, { "merchant_id": 6321, "open_charges_count": 0, "open_charges_amount": "0.000000", "draft_invoices_count": 2, "draft_invoices_amount": "257.750000", "unpaid_invoices_count": 1, "unpaid_invoices_amount": "99.990000", "billing_currency": "USD" } ] ``` --- ## Charges View and manage billing charges for fulfillment services. ### List charges **GET** `/billing/charges` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | No | Search language filter. Supported fields: `category` (string), `description` (string), `invoice` (null check, use `invoice^"null"` or `invoice!^"null"`), `voided_at` (null check, use `voided_at^"null"` or `voided_at!^"null"`), `created_at` (date, requires the `$DATE` modifier and supports the `:`, `>`, `>=`, `<`, `<=` operators with a `YYYY-MM-DD` value). Clauses can be combined with `AND` / `OR`. Example: `created_at$DATE>="2026-01-15"` | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of charges Content-Type: `application/json` ```json { "data": [ { "id": 11, "charger_id": 8617, "charger_type": "company", "chargee_id": 6320, "chargee_type": "team", "created_at": "2026-01-08T16:42:25.943180Z", "currency": "USD", "price": 521, "status": "Invoiced", "category": "OutboundShipment", "description": "Services charges for outbound shipment: Quantum Dynamics.", "amount": 521, "invoice_id": 133, "stripe_invoice_item_id": null } ], "total": 11, "current_page": 1, "last_page": 2, "per_page": 10, "from": 0, "to": 10 } ``` ### Show a charge **GET** `/billing/charges/{charge}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | charge | integer | Yes | The ID of the charge | #### Expected Response Status: `200` A successful response returning the charge and its items Content-Type: `application/json` ```json { "charge": { "id": 67, "charger_id": 1, "charger_type": "company", "chargee_id": 1, "chargee_type": "team", "created_at": "2023-08-31T14:00:39.000000Z", "currency": "USD", "price": 1.24, "status": "Open", "category": "OutboundShipment", "description": "Services charges for outbound shipment (FBA ID: FBA0LUMFEZQ3W): receive outbound.", "amount": 1.24, "invoice_id": null, "stripe_invoice_item_id": null }, "charge_items": [ { "id": 901, "charge_id": 67, "parent_id": null, "chargeable_item": null, "chargeable_item_id": 66, "chargeable_item_type": "outbound-shipment", "description": "Outbound Shipment, FBA ID: FBA0LUMFEZQ3W", "is_amendment": false, "units": 1, "unit_price_amount": 0, "line_price_amount": 0 } ] } ``` ### Store a quick adjustment charge **POST** `/billing/charges/quick-adjustment` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | amount | number | Yes | The amount of the adjustment | | description | string | Yes | A description of the adjustment | #### Expected Response Status: `201` A successful response returning the created charge and its items Content-Type: `application/json` ```json { "message": "Adjustment charged to client account.", "charge": { "id": 307, "charger_id": 1, "charger_type": "company", "chargee_id": 1, "chargee_type": "team", "created_at": "2024-05-21T18:50:31.496429Z", "currency": "USD", "price": 10, "status": "Open", "category": "Adjustment", "description": "Storage", "amount": 10, "invoice_id": null, "stripe_invoice_item_id": null }, "charge_items": [ { "id": 1093, "charge_id": 307, "parent_id": null, "chargeable_item": null, "chargeable_item_id": null, "chargeable_item_type": null, "description": "Storage", "is_amendment": false, "units": 1, "unit_price_amount": 10, "line_price_amount": 10 } ] } ``` --- ## Invoices View and manage billing invoices. ### List invoices **GET** `/billing/invoices` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | No | Search language filter. Supported fields: `id` (integer), `stripe_invoice_id` (string), `created_at` (date, requires the `$DATE` modifier and supports the `:`, `>`, `>=`, `<`, `<=` operators with a `YYYY-MM-DD` value). Clauses can be combined with `AND` / `OR`. Example: `created_at$DATE>="2026-01-15"` | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of invoices Content-Type: `application/json` ```json { "data": [ { "id": 129, "charger_id": 8617, "charger_type": "company", "chargee_id": 6320, "chargee_type": "team", "created_at": "2026-01-08T17:20:05Z", "currency": "USD", "status": "Draft", "stripe_invoice_status": null, "stripe_invoice_id": null, "description": null, "total": 257.75, "stripe_automatic_tax": { "enabled": null } } ], "total": 2, "current_page": 1, "last_page": 1, "per_page": 10, "from": 0, "to": 10 } ``` ### Create an invoice **POST** `/billing/invoices` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | charge_ids | array | No | Optional array of charge IDs to include in the invoice. If omitted, all uninvoiced charges will be included. | #### Expected Response Status: `200` A successful response returning the created invoice Content-Type: `application/json` ```json { "message": "Draft invoice created.", "invoice": { "id": 2, "charger_id": 1, "charger_type": "company", "chargee_id": 1, "chargee_type": "team", "created_at": "2023-08-09T16:39:26.558994Z", "currency": "USD", "status": "Draft", "stripe_invoice_status": null, "stripe_invoice_id": null, "description": null, "total": 293.8, "stripe_automatic_tax": { "enabled": null } }, "invoices": [ { "id": 2, "charger_id": 1, "charger_type": "company", "chargee_id": 1, "chargee_type": "team", "created_at": "2023-08-09T16:39:26.558994Z", "currency": "USD", "status": "Draft", "stripe_invoice_status": null, "stripe_invoice_id": null, "description": null, "total": 293.8, "stripe_automatic_tax": { "enabled": null } } ] } ``` ### Finalize an invoice Locks a draft invoice, preventing further modification to its charges. Once finalized, the invoice will be queued for creation on Stripe. This is a required step before attempting to collect payment. **POST** `/billing/invoices/{invoice}/finalize` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | invoice | integer | Yes | The ID of the invoice to finalize | #### Expected Response Status: `200` The invoice was successfully finalized (or was already finalized) Content-Type: `application/json` ```json { "message": "Invoice finalized and locked." } ``` ### Collect payment for an invoice Triggers an immediate charge attempt against the merchant's payment method on file for a finalized invoice. The invoice must be finalized before collection can be attempted. If the invoice has not yet been created on Stripe, this endpoint will create and finalize it on Stripe before attempting collection. **POST** `/billing/invoices/{invoice}/collect` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | invoice | integer | Yes | The ID of the invoice to collect payment for | #### Expected Response Status: `200` Payment collection was successfully initiated (or the invoice was already paid) Content-Type: `application/json` ```json { "message": "Payment collection initiated." } ``` --- ## Products Viewing product details. Stock quantities are served separately. ### List products Get a paginated list of products for the current merchant. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. Returns product details only — use the stock endpoints for quantities. Deleted products are excluded. **GET** `/products` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | No | Search language filter. Supported fields: `uuid` (uuid), `merchant_sku` (string), `title` (string). Substring matches require at least 3 characters. Clauses can be combined with `AND` / `OR`. Example: `title~"widget" AND merchant_sku:"WIDGET-001"` | | sorts | array | No | Sort the results. Sorting by stock quantities is not supported here — products and stock are separate resources. Example: `sorts[0][field]=title&sorts[0][order]=1` | | expand | array | No | Relations to include in each product. Omitted relations are absent from the response rather than null. Any other value is rejected with a 422. Example: `expand[]=identifiers&expand[]=tags` | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of products per page | #### Expected Response Status: `200` A successful response returning the paginated list of products Content-Type: `application/json` ```json { "data": [ { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "merchant_sku": "Synergist-163839", "title": "Synergistic Leather Shoes", "dimensions": { "length": 91, "width": 286, "height": 174, "unit": "mm" }, "weight": { "value": 1076, "unit": "g" }, "are_dimensions_locked": false, "is_deleted": false } ], "total": 37, "current_page": 1, "last_page": 4, "per_page": 10, "from": 1, "to": 10 } ``` ### Create a product Create a product for the current merchant. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. `merchant_sku` must be unique among the merchant's products that have not been deleted, so a SKU freed up by deleting a product can be reused. **POST** `/products` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | merchant_sku | string | Yes | The merchant's own Stock Keeping Unit identifier. Must be unique among the merchant's products. | | title | string | Yes | The title or name of the product | | dimensions | object | No | The measurements of the product, written as a single field. All three measurements and the unit must be sent together; sending `null` clears all three. Each measurement must convert to between 1 and 500000 millimetres, and is rounded to the nearest millimetre when stored. | | weight | object | No | The weight of the product, written as a single field. The value and the unit must be sent together; sending `null` clears the weight. The value must convert to between 1 and 500000 grams, and is rounded to the nearest gram when stored. | #### Expected Response Status: `201` A successful response returning the created product Content-Type: `application/json` ```json { "data": { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:55.000000Z", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "merchant_sku": "WIDGET-001", "title": "Blue Widget", "dimensions": { "length": 150, "width": 100, "height": 50, "unit": "mm" }, "weight": { "value": 500, "unit": "g" }, "are_dimensions_locked": false, "is_deleted": false, "images": [], "identifiers": [], "tags": [] } } ``` ### Get a product Get a single product by its UUID, including its images, identifiers and tags. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. Returns product details only — use the stock endpoints for quantities. Deleted products are returned with `is_deleted` set to true. **GET** `/products/{product_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | product_uuid | string | Yes | The UUID of the product | #### Expected Response Status: `200` A successful response returning the product Content-Type: `application/json` ```json { "data": { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "merchant_sku": "Synergist-163839", "title": "Synergistic Leather Shoes", "dimensions": { "length": 91, "width": 286, "height": 174, "unit": "mm" }, "weight": { "value": 1076, "unit": "g" }, "are_dimensions_locked": false, "is_deleted": false, "images": [ { "id": 512, "product_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "large_url": "https://example.com/images/512-large.jpg", "thumbnail_url": "https://example.com/images/512-thumb.jpg" } ], "identifiers": [ { "id": 1044, "product_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "identifier": "B014IA92I8", "identifier_type": "ASIN", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:55.000000Z" } ], "tags": [] } } ``` ### Update a product Update a product's details. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. Only the properties present in the request body are changed; omitted properties are left as they are. A property sent as `null` is cleared. `dimensions` and `weight` are each written as a whole: their measurements and the unit must be sent together, and sending one as `null` clears it. When the product has `are_dimensions_locked` set, sending `dimensions` or `weight` returns a 422. Deleted products cannot be updated and return a 404. **PUT** `/products/{product_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | product_uuid | string | Yes | The UUID of the product | | title | string | No | The title or name of the product | | dimensions | object | No | The measurements of the product, written as a single field. All three measurements and the unit must be sent together; sending `null` clears all three. Each measurement must convert to between 1 and 500000 millimetres, and is rounded to the nearest millimetre when stored. | | weight | object | No | The weight of the product, written as a single field. The value and the unit must be sent together; sending `null` clears the weight. The value must convert to between 1 and 500000 grams, and is rounded to the nearest gram when stored. | #### Expected Response Status: `200` A successful response returning the updated product Content-Type: `application/json` ```json { "data": { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "merchant_sku": "Synergist-163839", "title": "Blue Widget", "dimensions": { "length": 150, "width": 100, "height": 50, "unit": "mm" }, "weight": { "value": 500, "unit": "g" }, "are_dimensions_locked": false, "is_deleted": false, "images": [], "identifiers": [], "tags": [] } } ``` ### Delete a product Delete a product. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. The product is soft deleted: it disappears from the list endpoint, is still readable on the detail endpoint with `is_deleted` set to true, and frees its `merchant_sku` for reuse. Deleting a product that already has stock history requires the `products:delete_with_history` privilege and otherwise returns a 403. Deleting an already deleted product returns a 404. **DELETE** `/products/{product_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | product_uuid | string | Yes | The UUID of the product | #### Expected Response Status: `204` The product was successfully deleted Body: no response body is defined by the spec. --- ## Suppliers Viewing and managing suppliers, their catalogue items, cost tiers and identifiers ### List suppliers Get a paginated list of suppliers for the current merchant. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. Deleted suppliers are excluded. **GET** `/suppliers` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | No | Search language filter. Supported fields: `name` (string), `uuid` (uuid). Substring matches require at least 3 characters. Clauses can be combined with `AND` / `OR`. Example: `name~"acme"` | | sorts | array | No | Sort the results. Example: `sorts[0][field]=name&sorts[0][order]=1` | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of suppliers per page | #### Expected Response Status: `200` A successful response returning the paginated list of suppliers Content-Type: `application/json` ```json { "data": [ { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "name": "Acme Wholesale", "default_currency": "USD", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } ], "total": 1, "current_page": 1, "last_page": 1, "per_page": 10, "from": 1, "to": 1 } ``` ### Create a supplier Create a supplier for the current merchant. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. **POST** `/suppliers` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | Yes | The name of the supplier | | default_currency | string | Yes | The ISO 4217 currency code used to pre-fill new cost tiers for this supplier's items | #### Expected Response Status: `201` A successful response returning the created supplier Content-Type: `application/json` ```json { "data": { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "name": "Acme Wholesale", "default_currency": "USD", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:55.000000Z", "is_deleted": false } } ``` ### Get a supplier Get a single supplier by its UUID. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. Deleted suppliers are returned with `is_deleted` set to true. **GET** `/suppliers/{supplier_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | #### Expected Response Status: `200` A successful response returning the supplier Content-Type: `application/json` ```json { "data": { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "name": "Acme Wholesale", "default_currency": "USD", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } } ``` ### Update a supplier Update a supplier's details. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. Only the properties present in the request body are changed; omitted properties are left as they are. Deleted suppliers cannot be updated and return a 404. **PUT** `/suppliers/{supplier_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | name | string | No | The name of the supplier | | default_currency | string | No | The ISO 4217 currency code used to pre-fill new cost tiers for this supplier's items | #### Expected Response Status: `200` A successful response returning the updated supplier Content-Type: `application/json` ```json { "data": { "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "name": "Acme Wholesale", "default_currency": "USD", "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } } ``` ### Delete a supplier Delete a supplier. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. The supplier is soft deleted: it disappears from the list endpoint and is still readable on the detail endpoint with `is_deleted` set to true. Deleting an already deleted supplier returns a 404. **DELETE** `/suppliers/{supplier_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | #### Expected Response Status: `204` The supplier was successfully deleted Body: no response body is defined by the spec. ### List supplier items Get a paginated list of items for a supplier. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier outside the narrated account returns a 404. Deleted items are excluded. **GET** `/suppliers/{supplier_uuid}/items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | q | string | No | Search language filter. Supported fields: `sku` (string), `description` (string). Substring matches require at least 3 characters. Clauses can be combined with `AND` / `OR`. Example: `sku~"widget"` | | product_uuid | string | No | Filter items linked to this product | | sorts | array | No | Sort the results. Example: `sorts[0][field]=sku&sorts[0][order]=1` | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of supplier items Content-Type: `application/json` ```json { "data": [ { "uuid": "2b6f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d5", "supplier_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "sku": "ACME-WIDGET-001", "description": "Blue widget, bulk pack of 10", "product_uuid": null, "costs": [ { "minimum_order_quantity": 100, "current_cost": { "uuid": "3c7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d6", "amount": "12.3700", "currency": "USD", "effective_at": "2026-04-01T09:34:55.000000Z" }, "upcoming_cost": null } ], "identifiers": [ { "type": "UPC", "value": "123456789012" } ], "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } ], "total": 1, "current_page": 1, "last_page": 1, "per_page": 10, "from": 1, "to": 1 } ``` ### Create a supplier item Create a catalogue item for a supplier. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier outside the narrated account returns a 404. `sku` must be unique among the supplier's items that have not been deleted. `product_uuid`, when present, must reference a non-deleted product owned by the same merchant. **POST** `/suppliers/{supplier_uuid}/items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | sku | string | Yes | The supplier's own identifier for this item. Unique among the supplier's items that have not been deleted. | | description | string | No | A description of the item | | product_uuid | string | No | The UUID of the product this supplier item is linked to. Must be a non-deleted product owned by the same merchant. | | costs | array | No | Quantity-break cost tiers for this item. Minimum order quantities must be unique within the payload. | | costs.*.minimum_order_quantity | integer | Yes | | | costs.*.cost | object | Yes | | | costs.*.cost.amount | number | Yes | | | costs.*.cost.currency | string | Yes | | | identifiers | array | No | Typed barcode identifiers for this item. The combination of type and value must be unique within the payload. | | identifiers.*.type | string | Yes | | | identifiers.*.value | string | Yes | | #### Expected Response Status: `201` A successful response returning the created supplier item Content-Type: `application/json` ```json { "data": { "uuid": "2b6f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d5", "supplier_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "sku": "ACME-WIDGET-001", "description": "Blue widget, bulk pack of 10", "product_uuid": null, "costs": [ { "minimum_order_quantity": 100, "current_cost": { "uuid": "3c7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d6", "amount": "12.3700", "currency": "USD", "effective_at": "2026-04-01T09:34:55.000000Z" }, "upcoming_cost": null } ], "identifiers": [ { "type": "UPC", "value": "123456789012" } ], "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:55.000000Z", "is_deleted": false } } ``` ### Get a supplier item Get a single supplier item by its UUID, including its cost tiers and identifiers. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier or item outside the narrated account returns a 404. Deleted items are returned with `is_deleted` set to true. **GET** `/suppliers/{supplier_uuid}/items/{supplier_item_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | supplier_item_uuid | string | Yes | The UUID of the supplier item | #### Expected Response Status: `200` A successful response returning the supplier item Content-Type: `application/json` ```json { "data": { "uuid": "2b6f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d5", "supplier_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "sku": "ACME-WIDGET-001", "description": "Blue widget, bulk pack of 10", "product_uuid": null, "costs": [ { "minimum_order_quantity": 100, "current_cost": { "uuid": "3c7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d6", "amount": "12.3700", "currency": "USD", "effective_at": "2026-04-01T09:34:55.000000Z" }, "upcoming_cost": null } ], "identifiers": [ { "type": "UPC", "value": "123456789012" } ], "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } } ``` ### Update a supplier item Update a supplier item's own attributes (`sku`, `description`, `product_uuid`). Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier or item outside the narrated account returns a 404. Only the properties present in the request body are changed; omitted properties are left as they are. Cost tiers and identifiers are managed separately: costs are append-only via `POST .../costs` and `DELETE .../costs/{supplier_item_cost_uuid}`, and identifiers are set-replaced via `PUT .../identifiers`. **PUT** `/suppliers/{supplier_uuid}/items/{supplier_item_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | supplier_item_uuid | string | Yes | The UUID of the supplier item | | sku | string | No | The supplier's own identifier for this item. Unique among the supplier's items that have not been deleted. | | description | string | No | A description of the item | | product_uuid | string | No | The UUID of the product this supplier item is linked to. Must be a non-deleted product owned by the same merchant. | #### Expected Response Status: `200` A successful response returning the updated supplier item Content-Type: `application/json` ```json { "data": { "uuid": "2b6f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d5", "supplier_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "sku": "ACME-WIDGET-001", "description": "Blue widget, bulk pack of 10", "product_uuid": null, "costs": [ { "minimum_order_quantity": 100, "current_cost": { "uuid": "3c7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d6", "amount": "12.3700", "currency": "USD", "effective_at": "2026-04-01T09:34:55.000000Z" }, "upcoming_cost": null } ], "identifiers": [ { "type": "UPC", "value": "123456789012" } ], "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } } ``` ### Delete a supplier item Delete a supplier item. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier or item outside the narrated account returns a 404. The item is soft deleted: it disappears from the list endpoint and is still readable on the detail endpoint with `is_deleted` set to true, and frees its `sku` for reuse. Deleting an already deleted item returns a 404. **DELETE** `/suppliers/{supplier_uuid}/items/{supplier_item_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | supplier_item_uuid | string | Yes | The UUID of the supplier item | #### Expected Response Status: `204` The supplier item was successfully deleted Body: no response body is defined by the spec. ### Create a supplier item cost row Appends a new price for a minimum order quantity. Costs are append-only: this always inserts a new row rather than editing an existing one, so this can be used both to add a brand-new tier and to record a price change for a tier that already exists — the tier's `current_cost` is simply whichever non-future row for that minimum order quantity has the latest `effective_at`. Set `effective_at` to a future date to schedule a price change in advance; it surfaces as `upcoming_cost` until that date arrives. Omit it (or send null) to take effect immediately. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier or item outside the narrated account returns a 404. **POST** `/suppliers/{supplier_uuid}/items/{supplier_item_uuid}/costs` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | supplier_item_uuid | string | Yes | The UUID of the supplier item | | minimum_order_quantity | integer | Yes | | | cost | object | Yes | | | cost.amount | number | Yes | | | cost.currency | string | Yes | | | effective_at | string | No | The ISO 8601 datetime from which this price takes effect. Defaults to now when omitted or null; a future value schedules the price and surfaces it as `upcoming_cost` until it arrives. | #### Expected Response Status: `201` A successful response returning the created cost row Content-Type: `application/json` ```json { "data": { "uuid": "3c7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d6", "minimum_order_quantity": 100, "cost": { "amount": "12.3700", "currency": "USD" }, "effective_at": "2026-04-01T09:34:55.000000Z" } } ``` ### Delete a supplier item cost row Soft deletes a single cost row by its own UUID, preserving its price history. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier, item, or cost row outside the narrated account returns a 404. Deleting the row currently in effect for a minimum order quantity does not retire the tier: the next most recent non-future row for that quantity, if any, becomes current again. **DELETE** `/suppliers/{supplier_uuid}/items/{supplier_item_uuid}/costs/{supplier_item_cost_uuid}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | supplier_item_uuid | string | Yes | The UUID of the supplier item | | supplier_item_cost_uuid | string | Yes | The UUID of the cost row | #### Expected Response Status: `204` The cost row was successfully deleted Body: no response body is defined by the spec. ### Replace a supplier item's identifiers Replaces every existing identifier for this item with exactly the identifiers present in the payload. Requires a merchant scope; a service provider scope is optional, and a request without a merchant scope returns a 422. A supplier or item outside the narrated account returns a 404. The combination of type and value must be unique within the payload. Send an empty array to remove every existing identifier. **PUT** `/suppliers/{supplier_uuid}/items/{supplier_item_uuid}/identifiers` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | supplier_uuid | string | Yes | The UUID of the supplier | | supplier_item_uuid | string | Yes | The UUID of the supplier item | | identifiers | array | Yes | The complete set of identifiers for this item. Must always be present, even as an empty array, to clear every identifier. | | identifiers.*.type | string | Yes | | | identifiers.*.value | string | Yes | | #### Expected Response Status: `200` A successful response returning the updated supplier item Content-Type: `application/json` ```json { "data": { "uuid": "2b6f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d5", "supplier_uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "merchant_uuid": "9c1f2b3d-4e5a-4b6c-8d7e-0f1a2b3c4d5e", "sku": "ACME-WIDGET-001", "description": "Blue widget, bulk pack of 10", "product_uuid": null, "costs": [], "identifiers": [ { "type": "UPC", "value": "123456789012" } ], "created_at": "2026-04-01T09:34:55.000000Z", "updated_at": "2026-04-01T09:34:59.000000Z", "is_deleted": false } } ``` --- ## Inventory Viewing and managing inventory items ### List inventory items Get a paginated list of inventory items for the current merchant or service provider. **GET** `/inventory` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | No | A search query to filter items by title, SKU, identifier, tag, or condition | | ids | array | No | Filter items by a list of item IDs | | merchant_skus | array | No | Filter items by a list of merchant SKUs | | tag_ids | array | No | Filter items by a list of tag IDs | | available_quantity_gt | integer | No | Filter items with available quantity greater than this value | | available_quantity_lt | integer | No | Filter items with available quantity less than this value | | quantity_in_stock_gt | integer | No | Filter items with quantity in stock greater than this value | | quantity_in_stock_lt | integer | No | Filter items with quantity in stock less than this value | | missing_dimensions_only | boolean | No | When true, only return items missing dimension data | | sort_by | string | No | The field to sort results by | | sort_dir | string | No | The sort direction | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of inventory items Content-Type: `application/json` ```json { "current_page": 1, "last_page": 1, "from": 1, "to": 1, "data": [ { "id": 96, "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "created_at": "2022-04-01T09:34:55.000000Z", "updated_at": "2022-04-01T09:34:59.000000Z", "merchant_id": 2, "team_id": 2, "merchant_sku": "Synergist-163839", "title": "Synergistic Leather Shoes", "condition": "new", "condition_note": null, "are_dimensions_locked": false, "length_mm": 91, "width_mm": 286, "height_mm": 174, "weight_gm": 1076, "quantity_in_stock": 0, "fnskus": [ "X008VSER78", "X00U2E5ZYE" ], "fnsku": "X008VSER78", "asin": "B014IA92I8", "searchableIdentifiers": "B014IA92I8,X008VSER78,X00U2E5ZYE,3495184061393", "images": [], "identifiers": [] } ], "per_page": 500, "total": 37 } ``` ### Create an inventory item Create a new inventory item for the current merchant. **POST** `/inventory` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | merchant_sku | string | Yes | The merchant's own SKU for this item | | title | string | Yes | The title or name of the item | | condition | string | No | The condition of the item | | condition_note | string | No | Additional notes about the condition | | length_mm | integer | No | The length in millimetres | | width_mm | integer | No | The width in millimetres | | height_mm | integer | No | The height in millimetres | | weight_gm | integer | No | The weight in grams | #### Expected Response Status: `201` The inventory item was successfully created Content-Type: `application/json` ```json { "data": { "id": 2362, "uuid": "2f8b1c3e-d4a5-4e6f-b7c8-e9d0f1a2b3c4", "created_at": "2025-03-12T09:42:40Z", "updated_at": "2025-03-12T09:42:40Z", "merchant_id": 2, "team_id": 2, "merchant_sku": "0D-O2GN-CNH9", "title": "Test", "condition": null, "condition_note": null, "are_dimensions_locked": null } } ``` ### Search inventory items Search for inventory items using a text query and optional filters. **POST** `/inventory/search` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | Yes | The search query string | | mode | string | No | The search mode to use. Defaults to 'default'. | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | | filters | object | No | Optional filters to apply to the search | #### Expected Response Status: `200` A successful response returning matching inventory items Content-Type: `application/json` ```json { "current_page": 1, "data": [ { "id": 9, "uuid": "3a9c2d4e-f5b6-4c7d-a8e9-f0a1b2c3d4e5", "created_at": "2021-02-19T14:11:38.000000Z", "updated_at": "2021-02-19T14:11:38.000000Z", "merchant_id": 2, "team_id": 2, "merchant_sku": "Heavy-Duty-979091", "title": "Heavy Duty Wool Keyboard", "condition": null, "condition_note": null, "are_dimensions_locked": false, "length_mm": 589, "width_mm": 212, "height_mm": 509, "weight_gm": 3602, "fnskus": [ "X00U2E5ZYE", "X008VSER78" ], "fnsku": "X00U2E5ZYE", "asin": "B07611F2KY", "images": [], "identifiers": [], "company_services": [] } ], "first_page_url": "https://example.com/api/inventory/search?page=1", "from": 1, "items": [ { "id": 9, "uuid": "3a9c2d4e-f5b6-4c7d-a8e9-f0a1b2c3d4e5", "created_at": "2021-02-19T14:11:38.000000Z", "updated_at": "2021-02-19T14:11:38.000000Z", "merchant_id": 2, "team_id": 2, "merchant_sku": "Heavy-Duty-979091", "title": "Heavy Duty Wool Keyboard", "condition": null, "condition_note": null, "are_dimensions_locked": false, "length_mm": 589, "width_mm": 212, "height_mm": 509, "weight_gm": 3602, "fnskus": [ "X00U2E5ZYE", "X008VSER78" ], "fnsku": "X00U2E5ZYE", "asin": "B07611F2KY", "images": [], "identifiers": [], "company_services": [] } ], "last_page": 1, "last_page_url": "https://example.com/api/inventory/search?page=1", "links": [ { "url": null, "label": "« Previous", "active": false }, { "url": "https://example.com/api/inventory/search?page=1", "label": "1", "active": true }, { "url": null, "label": "Next »", "active": false } ], "next_page_url": null, "path": "https://example.com/api/inventory/search", "per_page": 10, "prev_page_url": null, "to": 1, "total": 1 } ``` ### Show an inventory item Get a single inventory item by its ID. **GET** `/inventory/{item}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | item | integer | Yes | The ID of the inventory item | #### Expected Response Status: `200` A successful response returning the inventory item Content-Type: `application/json` ```json { "item": { "id": 50, "uuid": "4b0d3e5f-a6c7-4d8e-b9f0-a1b2c3d4e5f6", "created_at": "2024-04-15T08:23:47.000000Z", "updated_at": "2024-04-15T08:23:47.000000Z", "deleted_at": null, "merchant_id": 2, "team_id": 2, "merchant_sku": "Recycled-Pa-443089", "title": "Recycled Paper Notebooks", "condition": "new", "condition_note": null, "are_dimensions_locked": false, "length_mm": 68, "width_mm": 140, "height_mm": 120, "weight_gm": 540, "quantity_in_stock": 0, "available_quantity": 0, "allocated_quantity": 0, "unavailable_quantity": 0, "inbound_quantity": 0, "history": [], "images": [], "identifiers": [], "tags": [], "production_formulas": [], "item_group_configurations": [], "company_services": [], "stocks": [], "traceability_groups": [] } } ``` ### Update an inventory item Update an existing inventory item. **PUT** `/inventory/{item}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | item | integer | Yes | The ID of the inventory item | | title | string | No | The title or name of the item | | condition | string | No | The condition of the item | | condition_note | string | No | Additional notes about the condition | | length_mm | integer | No | The length in millimetres | | width_mm | integer | No | The width in millimetres | | height_mm | integer | No | The height in millimetres | | weight_gm | integer | No | The weight in grams | #### Expected Response Status: `200` The inventory item was successfully updated Content-Type: `application/json` ```json { "message": "Item updated", "item": { "id": 151, "created_at": "2024-04-03T11:19:35.000000Z", "updated_at": "2024-04-03T11:19:35.000000Z", "merchant_id": 2, "merchant_sku": "3J-NO51-ICT7", "title": "Test Title", "condition": "new", "condition_note": null, "length_mm": 140, "width_mm": 140, "height_mm": 140, "weight_gm": 240, "fnskus": [], "fnsku": "", "asin": "", "searchableIdentifiers": "", "images": [], "identifiers": [] } } ``` ### Add an identifier to an inventory item Add a new identifier (ASIN, EAN, UPC, FNSKU, GTIN, or CUSTOM) to an inventory item. **POST** `/inventory/{item}/identifier` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | item | integer | Yes | The ID of the inventory item | | identifier_type | string | Yes | The type of identifier to add | | identifier | string | Yes | The identifier value | #### Expected Response Status: `200` The identifier was successfully added Content-Type: `application/json` ```json { "identifier": { "id": 1, "identifier": "B0001234AB", "identifier_type": "ASIN" } } ``` ### Manage services for an inventory item Sync the company services associated with an inventory item. **POST** `/inventory/services` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | item_id | integer | Yes | The ID of the inventory item | | services | array | Yes | The list of company service IDs to associate with the item | #### Expected Response Status: `200` The services were successfully synced Content-Type: `application/json` ```json { "message": "Services Updated" } ``` ### Delete an inventory item identifier Delete an identifier (ASIN, EAN, UPC, FNSKU, GTIN, or CUSTOM) from an inventory item. **DELETE** `/identifier/{identifier}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | identifier | integer | Yes | The ID of the inventory item identifier to delete | #### Expected Response Status: `200` A successful response after deleting the identifier Content-Type: `application/json` ```json { "message": "Identifier deleted" } ``` ### Batch delete inventory items Delete multiple inventory items at once. **POST** `/inventory/batch/delete` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | items | array | Yes | The inventory items to delete | | items.*.id | integer | Yes | The ID of the inventory item to delete | #### Expected Response Status: `200` A successful response after deleting the inventory items Content-Type: `application/json` ```json { "message": "Items deleted" } ``` --- ## Inbound Shipments Viewing and managing inbound shipments and their items ### List inbound shipments Get a paginated list of active (non-archived) inbound shipments. **GET** `/shipments/inbound` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | filters[not_received] | boolean | No | When true, only return shipments that have not yet been received | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of inbound shipments Content-Type: `application/json` ```json { "current_page": 1, "data": [ { "id": 39, "created_at": "2022-03-26T10:23:55.000000Z", "updated_at": "2022-03-28T12:52:00.000000Z", "merchant_id": 2, "team_id": 2, "name": "Crooks, Reilly and Predovic", "notes": "Ipsam et quaerat voluptates iure quae.", "status": "shipped", "warehouse_id": 1, "received_at": null, "internal_notes": null, "archived_at": null, "expected_quantity": 680, "sku_count": 7, "actual_quantity": 0, "unsellable_quantity": 4, "received_quantity": 4, "reference_id": "INSH-032622-39", "searchable_identifiers": "B01N1KM25E,X00FK2YTUF,0751765057210" } ], "from": 1, "last_page": 2, "per_page": 20, "to": 20, "total": 30 } ``` ### Create an inbound shipment Create a new inbound shipment for the current merchant. **POST** `/shipments/inbound` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | Yes | The name of the shipment | | warehouse_id | integer | Yes | The ID of the destination warehouse | | notes | string | No | Optional notes about the shipment | #### Expected Response Status: `201` The inbound shipment was successfully created Content-Type: `application/json` ```json { "message": "Shipment created", "shipment_id": 22 } ``` ### List archived inbound shipments Get a paginated list of archived inbound shipments. **GET** `/shipments/inbound/archived` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of archived inbound shipments Content-Type: `application/json` ```json { "data": [ { "id": 1001, "uuid": "1e7f0a0f-b5a9-4d1a-a2d5-d0e0c2b1c3d4", "created_at": "2024-01-15T12:00:00Z", "updated_at": "2024-01-15T12:00:00Z", "deleted_at": "2026-01-01T00:00:00Z", "checked_in_at": "2026-01-01T00:00:00Z", "name": "January Restock 2024", "notes": "Handle with care", "internal_notes": "Customer requested priority processing", "merchant_id": 42, "team_id": 42, "warehouse_id": 5, "reference_id": "INSH-011524-1001", "status": "open", "shipped_at": "2024-01-20T10:00:00Z", "received_at": "2024-01-25T14:30:00Z", "archived_at": null, "eta": "2024-01-24T00:00:00Z", "currency": "USD", "sku_count": 1, "expected_quantity": 1, "actual_quantity": 1, "unsellable_quantity": 1, "received_quantity": 1, "searchable_identifiers": "string", "searchable_tags": [ "string" ], "tags": [ { "id": 1, "name": "string" } ], "attachments": [ { "id": 1, "name": "string", "url": "string", "path": "string" } ], "service_lines": [ { "id": 1, "quantity": 1 } ], "tracking_numbers": [], "shipment_id": "string" } ], "total": 42, "current_page": 1, "last_page": 5, "per_page": 10, "from": 1, "to": 10, "first_page_url": "string", "last_page_url": "string", "next_page_url": "string", "prev_page_url": "string", "path": "string", "links": [] } ``` ### Show an inbound shipment Get a single inbound shipment by its ID, including attachments, service lines, warehouse, and tags. **GET** `/shipments/inbound/{inbound_shipment}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | #### Expected Response Status: `200` A successful response returning the inbound shipment Content-Type: `application/json` ```json { "shipment": { "id": 19, "created_at": "2024-01-26T14:51:01.000000Z", "updated_at": "2024-01-29T07:18:52.000000Z", "merchant_id": 1, "team_id": 1, "name": "Binary Burst 12", "notes": "Validate shipment contents against packing list to ensure accuracy.", "warehouse_id": 1, "received_at": null, "internal_notes": null, "archived_at": null, "shipped_at": "2024-01-26T14:51:01.000000Z", "checked_in_at": null, "deleted_at": null, "currency": "USD", "eta": "2024-01-23T09:51:01Z", "expected_quantity": 310, "sku_count": 5, "shipment_id": null, "actual_quantity": 0, "unsellable_quantity": 0, "received_quantity": 0, "reference_id": "INSH-012624-19", "status": "shipped", "tracking_numbers": [], "attachments": [], "service_lines": [], "warehouse": { "id": 1, "uuid": "0197e188-5d70-8010-bf60-252ed9687632", "name": "NY Warehouse" }, "tags": [] } } ``` ### Update an inbound shipment Update an existing inbound shipment. **PUT** `/shipments/inbound/{inbound_shipment}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | name | string | No | The name of the shipment | | notes | string | No | Notes about the shipment | | internal_notes | string | No | Internal notes visible only to staff | | eta | string | No | The estimated time of arrival | #### Expected Response Status: `200` The inbound shipment was successfully updated Content-Type: `application/json` ```json { "shipment": { "id": 46, "created_at": "2021-10-19T07:48:05.000000Z", "updated_at": "2021-10-26T17:29:18.000000Z", "merchant_id": 2, "name": "Lindgren-Cormier", "notes": "Inventore iusto facilis aperiam modi est.", "status": "shipped", "warehouse_id": 1, "received_at": null, "internal_notes": null } } ``` ### Delete an inbound shipment Delete an inbound shipment by its ID **DELETE** `/shipments/inbound/{inbound_shipment}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | #### Expected Response Status: `204` The inbound shipment was successfully deleted Body: no response body is defined by the spec. ### Submit an inbound shipment Mark an inbound shipment as shipped. Optionally include a carrier and tracking numbers. **POST** `/shipments/inbound/{inbound_shipment}/submit` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | carrier | string | No | The carrier used for shipping | | tracking_numbers | array | No | List of tracking numbers. Required when carrier is provided. | #### Expected Response Status: `200` The shipment was successfully submitted Content-Type: `application/json` ```json { "message": "Shipment submitted" } ``` ### Receive an inbound shipment Mark an inbound shipment as received at the warehouse. **POST** `/shipments/inbound/{inbound_shipment}/receive` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | #### Expected Response Status: `200` The shipment was successfully received Content-Type: `application/json` ```json { "message": "Shipment received" } ``` ### Add tracking to an inbound shipment Add tracking numbers from one carrier to an inbound shipment. The numbers are added alongside the shipment's existing tracking; a number the shipment already has is left unchanged. When no carrier is provided, the shipment is not changed. **POST** `/shipments/inbound/{inbound_shipment}/add-tracking` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | carrier | string | No | The carrier the tracking numbers belong to | | tracking_numbers | array | No | The tracking numbers to add. Required when carrier is provided. | #### Expected Response Status: `200` The tracking numbers were successfully added Content-Type: `application/json` ```json { "message": "Shipment updated." } ``` ### Batch archive inbound shipments Archive multiple inbound shipments at once. **POST** `/shipments/inbound/batch/archive` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | shipment_ids | array | Yes | The IDs of the shipments to archive | #### Expected Response Status: `200` The shipments were successfully archived Content-Type: `application/json` ```json { "message": "Shipments archived" } ``` --- ## Inbound Shipment Items Viewing and managing inbound shipments and their items ### List items for an inbound shipment Get the list of items (expected, actual, and unsellable) for an inbound shipment. **GET** `/shipments/inbound/{inbound_shipment}/items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | item_ids | array | No | Filter to a specific list of item IDs | #### Expected Response Status: `200` A successful response returning the shipment items Content-Type: `application/json` ```json { "items": [ { "id": 1, "item_id": 1, "shipment_id": 629, "expected": { "quantity": 10, "item_group_configurations": [], "id": 1072 }, "actual": { "quantity": 10, "item_group_configurations": [], "moves": [], "id": 830 }, "unsellable": { "quantity": 0 }, "item": { "id": 1, "merchant_sku": "Silicone-223984", "title": "1 - Silicone Baking Mats", "condition": "new" } } ] } ``` ### Add an item to an inbound shipment Add an inventory item with a specified quantity to an inbound shipment. **POST** `/shipments/inbound/{inbound_shipment}/add-item` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | item_id | integer | Yes | The ID of the inventory item to add | | quantity | integer | Yes | The expected quantity of the item | #### Expected Response Status: `200` The item was successfully added to the shipment Content-Type: `application/json` ```json { "message": "Item added to shipment" } ``` ### Update an item on an inbound shipment Update the expected and actual quantities for an item on an inbound shipment. **POST** `/shipments/inbound/{inbound_shipment}/update-item` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | item_id | integer | Yes | The ID of the inventory item to update | | expected | object | Yes | Expected quantity update | | expected.quantity | integer | Yes | The new expected quantity | | expected.item_group_configurations | array | No | Group configuration summaries | | expected.item_group_configurations.*.configuration_id | integer | No | | | expected.item_group_configurations.*.quantity | integer | No | | | expected.item_group_configurations.*.partial_quantity | integer | No | | | actual | object | No | Actual quantity update (only available to service provider staff) | | actual.quantity | integer | Yes | The new actual received quantity | | actual.item_group_configurations | array | No | Group configuration summaries | | actual.item_group_configurations.*.configuration_id | integer | No | | | actual.item_group_configurations.*.quantity | integer | No | | | actual.item_group_configurations.*.partial_quantity | integer | No | | | actual.moves | array | No | Stock move data | #### Expected Response Status: `200` The item was successfully updated Content-Type: `application/json` ```json { "message": "Item updated" } ``` ### Remove an item from an inbound shipment Remove an inventory item from an inbound shipment. **POST** `/shipments/inbound/{inbound_shipment}/remove-item` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_shipment | integer | Yes | The ID of the inbound shipment | | item_id | integer | Yes | The ID of the inventory item to remove | #### Expected Response Status: `200` The item was successfully removed from the shipment Content-Type: `application/json` ```json { "message": "Item removed from shipment" } ``` --- ## Outbound Shipments Viewing and managing outbound shipments and their items ### List outbound shipments **GET** `/shipments/outbound` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | filters[not_shipped] | boolean | No | Filter to only return shipments that have not been shipped | #### Expected Response Status: `200` A successful response returning the paginated list of outbound shipments Content-Type: `application/json` ```json { "current_page": 1, "last_page": 2, "from": 1, "to": 20, "data": [ { "id": 5657, "created_at": "2024-07-24T11:09:48.000000Z", "updated_at": "2024-07-24T11:13:07.000000Z", "merchant_id": 1, "status": "open", "notes": null, "name": "Test Plans", "warehouse_id": 1, "shipped_at": null, "internal_notes": null, "archived_at": null, "currency": "USD", "is_case_forwarding": false, "sku_count": 1, "shipped_items_count": 5, "searchable_identifiers": "B00LIRROR6,X00N2VJGHH", "searchable_tags": [], "tags": [], "fba_transport_plans": [] } ], "per_page": 20, "total": 22 } ``` ### Create an outbound shipment **POST** `/shipments/outbound` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | Yes | The name of the outbound shipment | | notes | string | No | Optional notes for the outbound shipment | | warehouse_id | integer | Yes | The ID of the warehouse for this shipment | #### Expected Response Status: `200` A successful response after creating the outbound shipment Content-Type: `application/json` ```json { "message": "Shipment Created", "shipment_id": 22 } ``` ### List archived outbound shipments **GET** `/shipments/outbound/archived` #### Expected Response Status: `200` A successful response returning the paginated list of archived outbound shipments Content-Type: `application/json` ```json { "data": [ { "id": 1, "reference_id": "OUSH-011524-1001", "uuid": "string", "name": "My FBA Shipment", "notes": "string", "internal_notes": "string", "status": "open", "merchant_id": 1, "team_id": 1, "warehouse_id": 1, "warehouse_uuid": "string", "customer_id": 1, "channel_id": 1, "ship_from_address_id": 1, "shipped_at": "2024-01-01T00:00:00Z", "archived_at": "string", "priced_at": "string", "cancellation_requested_at": "string", "cancellation_request_reason": "string", "cancellation_denied_at": "string", "cancellation_denial_reason": "string", "is_case_forwarding": true, "is_locked": true, "currency": "USD", "sku_count": 1, "shipped_items_count": 1, "pallets": [], "errors": [], "searchable_identifiers": "string", "searchable_tags": [ "string" ], "tags": [], "fba_transport_v2024_plans": [], "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "outbound_items": [], "service_lines": [], "attachments": [], "is_case_packed": true, "fba_transport_plans": [] } ], "total": 42, "current_page": 1, "last_page": 5, "per_page": 10, "from": 1, "to": 10, "first_page_url": "string", "last_page_url": "string", "next_page_url": "string", "prev_page_url": "string", "path": "string", "links": [] } ``` ### Get an outbound shipment **GET** `/shipments/outbound/{outbound_shipment}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment | integer | Yes | The ID of the outbound shipment | #### Expected Response Status: `200` A successful response returning the outbound shipment with its relations Content-Type: `application/json` ```json { "shipment": { "id": 6, "created_at": "2024-07-23T06:51:11.000000Z", "updated_at": "2024-06-04T12:45:12.000000Z", "merchant_id": 1, "status": "closed", "notes": null, "name": "Triton Tech", "warehouse_id": 1, "shipped_at": "2024-07-23T06:51:11.000000Z", "internal_notes": null, "errors": null, "ship_from_address_id": null, "archived_at": null, "currency": "USD", "is_case_forwarding": false, "is_case_packed": true, "outbound_items": [ { "id": 14, "shipment_id": 6, "item_id": 21, "quantity": 20, "case_quantity": null, "expiry_date": null, "item": { "id": 21, "merchant_sku": "Crystal-W-283235", "title": "Crystal Wine Decanter", "fnsku": "X007V73BAF", "asin": "B04Z6GUVL5" } } ], "service_lines": [], "attachments": [], "tags": [] } } ``` ### Upload an attachment to an outbound shipment **POST** `/shipments/outbound/{outbound_shipment}/attachment` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment | integer | Yes | The ID of the outbound shipment | #### Expected Response Status: `200` A successful response after uploading the attachment Content-Type: `application/json` ```json { "message": "Attachments have been uploaded to this shipment.", "attachments": [ { "path": "attachments/EZDXv1TmvIOkBKjysyDSiM8keDjs16yP5dYp661c1D6MUSCqSyib0LEydAzWirell2ZauIlBo3AG877UUYGZpcOiKp4cUW7wz9tzvFW13swQLPebryR4Lyxe.png", "name": "Manifest.xml", "url": "http://localhost:3001/storage/attachments/EZDXv1TmvIOkBKjysyDSiM8keDjs16yP5dYp661c1D6MUSCqSyib0LEydAzWirell2ZauIlBo3AG877UUYGZpcOiKp4cUW7wz9tzvFW13swQLPebryR4Lyxe.png", "attachable_id": 15, "attachable_type": "outbound-shipment", "updated_at": "2024-05-29T12:39:06.000000Z", "created_at": "2024-05-29T12:39:06.000000Z", "id": 1 } ] } ``` --- ## Outbound Shipment Items Viewing and managing outbound shipments and their items ### List items in an outbound shipment **GET** `/shipments/outbound/{outbound_shipment}/outbound-shipment-item` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment | integer | Yes | The ID of the outbound shipment | #### Expected Response Status: `200` A successful response returning the list of items in the outbound shipment Content-Type: `application/json` ```json { "items": [ { "id": 1387, "created_at": "2024-04-08T10:30:57.000000Z", "updated_at": "2024-04-08T10:30:57.000000Z", "shipment_id": 1455, "item_id": 3375, "quantity": 80, "expiry_date": null, "cost_per_item": 17.93, "item": { "id": 3375, "merchant_sku": "Mediocre-Ir-932762", "title": "Mediocre Iron Shoes", "condition": "new", "fnsku": "X0008OG4VD", "asin": "B01MRL790Q" }, "moves": [], "company_services": [] } ] } ``` ### Add an item to an outbound shipment **POST** `/shipments/outbound/{outbound_shipment}/outbound-shipment-item` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment | integer | Yes | The ID of the outbound shipment | | item_id | integer | Yes | The ID of the inventory item to add | | quantity | integer | Yes | The quantity of the item to add | | expiry_date | string | No | The expiry date for this item in YYYY-MM-DD format | #### Expected Response Status: `200` A successful response after adding the item to the shipment Content-Type: `application/json` ```json { "message": "Item added to shipment" } ``` ### Update an item in an outbound shipment **PATCH** `/shipments/outbound/{outbound_shipment}/outbound-shipment-item/{outbound_shipment_item}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment | integer | Yes | The ID of the outbound shipment | | outbound_shipment_item | integer | Yes | The ID of the outbound shipment item | | quantity | integer | No | The updated quantity of the item | | expiry_date | string | No | The updated expiry date in YYYY-MM-DD format | #### Expected Response Status: `200` A successful response after updating the item Content-Type: `application/json` ```json { "message": "Item updated" } ``` ### Remove an item from an outbound shipment **DELETE** `/shipments/outbound/{outbound_shipment}/outbound-shipment-item/{outbound_shipment_item}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment | integer | Yes | The ID of the outbound shipment | | outbound_shipment_item | integer | Yes | The ID of the outbound shipment item | #### Expected Response Status: `200` A successful response after deleting the item Content-Type: `application/json` ```json { "message": "Item deleted" } ``` --- ## FBA Plans Viewing and managing FBA transport plans ### List FBA transport v2024 plans **GET** `/fba-transport/v2024/plans` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment_id | integer | No | Filter plans by outbound shipment ID | #### Expected Response Status: `200` A successful response returning the list of FBA transport v2024 plans Content-Type: `application/json` ```json { "data": [ { "id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "created_at": "2025-09-16T17:59:28.000000Z", "updated_at": "2025-09-16T18:00:05.000000Z", "name": "Eagle Eye Engineering", "ship_from_address": { "name": "AL Warehouse", "address_line_1": "1300 Montgomery Highway", "address_line_2": "Suite 109", "company_name": null, "district_or_county": null, "city": "Vestavia Hills", "state_or_province_code": "AL", "country_code": "US", "postal_code": "35216-9520", "email": null, "phone_number": "1234567890" }, "marketplace": { "identifier": "ATVPDKIKX0DER", "country": "United States" }, "outbound_shipment_id": 5, "channel_id": 1, "inbound_plan_id": "XlJbBi51GdqP9yfQDUQA43EI0VrQ7mJdlzfLmY", "create_plan_operation_id": "019953ae-7a0d-7342-956a-881dcd7b2c81", "is_canceled": false, "using_2d_barcodes": false, "status": "ACTIVE", "items": [ { "id": "019953ae-7a0d-7342-956a-881dce3b8a23", "created_at": "2025-09-16T17:59:28.000000Z", "updated_at": "2025-09-16T17:59:29.000000Z", "msku": "Mini-Porta-276810", "fnsku": "X00SPO3LCY", "asin": "B00ZB18SIF", "quantity": 40, "label_owner": "SELLER", "prep_owner": "SELLER", "expiration": null, "manufacturing_lot_code": null } ], "packing_options": [], "is_packing_information_set": true, "isPackingInfoKnown": true, "box_groups": [], "placement_options": [] } ] } ``` ### Create an FBA transport v2024 shipping plan Creates a new Amazon FBA inbound shipping plan for an outbound shipment. The plan is created asynchronously via Amazon's Fulfillment Inbound API. Once created, use the returned plan to configure packing options, placement options, and transportation options before confirming the shipment. **POST** `/fba-transport/v2024/plans` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | outbound_shipment_id | integer | Yes | The ID of the outbound shipment to create a plan for | | channel_id | integer | Yes | The ID of the Amazon channel (must be an active Amazon channel) | | destination_marketplace | string | No | The Amazon marketplace identifier for the destination (e.g. ATVPDKIKX0DER for US). Defaults to the channel's marketplace if not provided. | | items | array | Yes | The items to include in the shipping plan | | items.*.msku | string | Yes | The merchant SKU for this item | | items.*.quantity | integer | Yes | The quantity of this item to include in the plan | | items.*.label_owner | string | Yes | Who will own the labeling responsibility for this item | | items.*.prep_owner | string | Yes | Who will own the prep responsibility for this item | | items.*.expiration | string | No | Optional expiration date for the item (YYYY-MM-DD) | | items.*.manufacturing_lot_code | string | No | Optional manufacturing lot code (1-256 characters) | #### Expected Response Status: `200` A successful response returning the newly created FBA transport v2024 plan Content-Type: `application/json` ```json { "data": { "id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "created_at": "2025-09-16T17:59:28.000000Z", "updated_at": "2025-09-16T18:00:05.000000Z", "name": "Eagle Eye Engineering", "ship_from_address": { "name": "AL Warehouse", "address_line_1": "1300 Montgomery Highway", "address_line_2": "Suite 109", "company_name": null, "district_or_county": null, "city": "Vestavia Hills", "state_or_province_code": "AL", "country_code": "US", "postal_code": "35216-9520", "email": null, "phone_number": "1234567890" }, "marketplace": { "identifier": "ATVPDKIKX0DER", "country": "United States" }, "outbound_shipment_id": 5, "channel_id": 1, "inbound_plan_id": "XlJbBi51GdqP9yfQDUQA43EI0VrQ7mJdlzfLmY", "create_plan_operation_id": "019953ae-7a0d-7342-956a-881dcd7b2c81", "is_canceled": false, "using_2d_barcodes": false, "status": "ACTIVE", "items": [ { "id": "019953ae-7a0d-7342-956a-881dce3b8a23", "created_at": "2025-09-16T17:59:28.000000Z", "updated_at": "2025-09-16T17:59:29.000000Z", "msku": "Mini-Porta-276810", "fnsku": "X00SPO3LCY", "asin": "B00ZB18SIF", "quantity": 40, "label_owner": "SELLER", "prep_owner": "SELLER", "expiration": null, "manufacturing_lot_code": null } ], "packing_options": [], "is_packing_information_set": false, "isPackingInfoKnown": false, "box_groups": [], "placement_options": [] } } ``` ### Get a FBA transport v2024 plan **GET** `/fba-transport/v2024/plans/{plan}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` A successful response returning the FBA transport v2024 plan Content-Type: `application/json` ```json { "data": { "id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "created_at": "2025-09-16T17:59:28.000000Z", "updated_at": "2025-09-16T18:00:05.000000Z", "name": "Eagle Eye Engineering", "ship_from_address": { "name": "AL Warehouse", "address_line_1": "1300 Montgomery Highway", "address_line_2": "Suite 109", "company_name": null, "district_or_county": null, "city": "Vestavia Hills", "state_or_province_code": "AL", "country_code": "US", "postal_code": "35216-9520", "email": null, "phone_number": "1234567890" }, "marketplace": { "identifier": "ATVPDKIKX0DER", "country": "United States" }, "outbound_shipment_id": 5, "channel_id": 1, "inbound_plan_id": "XlJbBi51GdqP9yfQDUQA43EI0VrQ7mJdlzfLmY", "create_plan_operation_id": "019953ae-7a0d-7342-956a-881dcd7b2c81", "is_canceled": false, "using_2d_barcodes": false, "status": "ACTIVE", "items": [ { "id": "019953ae-7a0d-7342-956a-881dce3b8a23", "created_at": "2025-09-16T17:59:28.000000Z", "updated_at": "2025-09-16T17:59:29.000000Z", "msku": "Mini-Porta-276810", "fnsku": "X00SPO3LCY", "asin": "B00ZB18SIF", "quantity": 40, "label_owner": "SELLER", "prep_owner": "SELLER", "expiration": null, "manufacturing_lot_code": null } ], "packing_options": [ { "id": "019953ae-8047-71b6-8214-cafa0b1eff32", "discounts": [], "expiration": null, "fees": [], "packing_option_id": "pocajn494QJgzId4JWtXCLdl1OyIEeR07fzOk7", "status": "OFFERED", "supported_shipping_configurations": [], "confirmed_at": "2025-09-16T17:59:31.000000Z", "packing_groups": [] } ], "is_packing_information_set": true, "box_groups": [], "placement_options": [] } } ``` ### Get shipment labels for an FBA transport v2024 plan **GET** `/fba-transport/v2024/plans/{plan}/labels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | The Amazon shipment ID to retrieve labels for | #### Expected Response Status: `200` A successful response returning the labels for the shipment Content-Type: `application/json` ```json { "data": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "created_at": "2025-12-15T15:00:07.000000Z", "updated_at": "2025-12-15T15:00:07.000000Z", "name": "Amazon Package/Carton Labels (8.5\" x 11\")", "url": "http://demo.conveyr.test/storage/fba-transport/SH-CONFIRM001/amazon-packagecarton-labels-85-x-11.pdf", "type": "package", "paper_size": "PackageLabel_Letter_2" } ] } ``` ### Request package labels **POST** `/fba-transport/v2024/plans/{plan}/request-package-labels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Shipping labels have been downloaded successfully." } ``` ### Request box labels **POST** `/fba-transport/v2024/plans/{plan}/request-box-labels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | No | | | shipment_id | string | Yes | | | box_numbers | array | No | | | sort_by_internal_number | boolean | No | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Requesting box labels" } ``` ### Request individual box labels **POST** `/fba-transport/v2024/plans/{plan}/request-individual-box-labels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | | | box_numbers | array | Yes | | | sort_by_internal_number | boolean | No | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Requesting individual box labels" } ``` ### Request pallet labels **POST** `/fba-transport/v2024/plans/{plan}/request-pallet-labels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | pallets | array | Yes | | | pallets.*.number | integer | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Pallet labels requested" } ``` ### Download pallet labels **POST** `/fba-transport/v2024/plans/{plan}/download-pallet-labels` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Pallet labels downloaded" } ``` ### Request bill of lading **POST** `/fba-transport/v2024/plans/{plan}/request-bill-of-lading` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Requesting bill of lading" } ``` ### Resize a shipment label to 4x6 **POST** `/fba-transport/v2024/plans/{plan}/labels/{label_id}/resize-to-4x6` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | label_id | string | Yes | | | shipment_id | string | Yes | | | sort_by_internal_number | boolean | No | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Generating resized labels, please wait 2-3 minutes for the process to complete" } ``` ### Create a box group for an FBA plan Creates a new box group defining the dimensions, weight, and associated packing entity for boxes in an FBA transport plan. Items (SKUs) and the number of physical boxes are configured separately after creation. **POST** `/fba-transport/v2024/plans/{plan}/box-groups` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | associated_entity_id | string | Yes | The Amazon packing group ID or shipment ID this box group belongs to | | length_mm | integer | Yes | The interior length of the box in millimetres | | width_mm | integer | Yes | The interior width of the box in millimetres | | height_mm | integer | Yes | The interior height of the box in millimetres | | weight_gm | integer | Yes | The total weight of a packed box in grams | #### Expected Response Status: `200` The newly created box group Content-Type: `application/json` ```json { "data": { "id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "length_mm": 300, "width_mm": 200, "height_mm": 150, "weight_gm": 5000, "packing_group_id": "packingGroupId-abc123", "box_numbers": [], "items": [] } } ``` ### Update a box group Updates the dimensions and weight of a box group. Cannot be called after packing information has been submitted — reset submissions first. **PUT** `/fba-transport/v2024/plans/{plan}/box-groups/{box_group_id}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | Yes | The ID of the box group | | length_mm | integer | Yes | The interior length of the box in millimetres | | width_mm | integer | Yes | The interior width of the box in millimetres | | height_mm | integer | Yes | The interior height of the box in millimetres | | weight_gm | integer | Yes | The total weight of a packed box in grams | #### Expected Response Status: `200` Box group updated successfully Content-Type: `application/json` ```json { "message": "Box group updated" } ``` ### Remove a box group Permanently deletes a box group and all of its boxes and items. **DELETE** `/fba-transport/v2024/plans/{plan}/box-groups/{box_group_id}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | Yes | The ID of the box group | #### Expected Response Status: `200` Box group removed successfully Content-Type: `application/json` ```json { "message": "Box group removed" } ``` ### Set the number of boxes in a box group Sets the number of physical boxes in a box group. Increasing the quantity creates new boxes with sequentially assigned numbers across all box groups in the plan. Decreasing the quantity removes the newest boxes. **POST** `/fba-transport/v2024/plans/{plan}/box-groups/{box_group_id}/set-box-quantity` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | Yes | The ID of the box group | | quantity | integer | Yes | The number of physical boxes in this group | #### Expected Response Status: `200` Box quantity updated successfully Content-Type: `application/json` ```json { "message": "Box quantity updated", "box_numbers": [ 1, 2, 3, 4, 5 ] } ``` ### Add an item to a box group Adds a plan item (SKU) to a box group, specifying how many units of that SKU are packed into each box in the group. Each plan item can only appear once per box group. **POST** `/fba-transport/v2024/plans/{plan}/box-groups/{box_group_id}/items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | Yes | The ID of the box group | | plan_item_id | string | Yes | The ID of the plan item (SKU) to add to this box group | | quantity | integer | Yes | The number of units of this SKU packed in each box in the group | #### Expected Response Status: `200` Item added to the box group successfully Content-Type: `application/json` ```json { "box_group_item": { "id": "019953ae-7a0d-7342-956a-881dcdbe42ae", "created_at": "2024-01-01T00:00:00Z", "plan_item_id": "019953ae-7a0d-7342-956a-881dce3b8a23", "msku": "Mini-Porta-276810", "quantity": 10 } } ``` ### Update an item in a box group Updates the quantity of a plan item (SKU) in a box group. Cannot be called after packing information has been submitted — reset submissions first. **PUT** `/fba-transport/v2024/plans/{plan}/box-groups/{box_group_id}/items/{box_group_item_id}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | Yes | The ID of the box group | | box_group_item_id | string | Yes | The ID of the box group item | | quantity | integer | Yes | The updated number of units of this SKU packed in each box in the group | #### Expected Response Status: `200` Item updated successfully Content-Type: `application/json` ```json { "box_group_item": { "id": "019953ae-7a0d-7342-956a-881dcdbe42ae", "created_at": "2024-01-01T00:00:00Z", "plan_item_id": "019953ae-7a0d-7342-956a-881dce3b8a23", "msku": "Mini-Porta-276810", "quantity": 12 }, "message": "Item updated" } ``` ### Remove an item from a box group Removes a plan item (SKU) from a box group. **DELETE** `/fba-transport/v2024/plans/{plan}/box-groups/{box_group_id}/items/{box_group_item_id}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | box_group_id | string | Yes | The ID of the box group | | box_group_item_id | string | Yes | The ID of the box group item | #### Expected Response Status: `200` Item removed successfully Content-Type: `application/json` ```json { "message": "Item removed" } ``` ### Add carton requests to a packing submission **POST** `/fba-transport/v2024/plans/{plan}/add-carton-request-to-submission` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | packing_group_ids | array | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Packing information set successfully" } ``` ### Generate packing options for an FBA plan **POST** `/fba-transport/v2024/plans/{plan}/generate-packing-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Fetch packing options from Amazon **GET** `/fba-transport/v2024/plans/{plan}/packing-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Packing options fetched and stored on the plan successfully. Body: no response body is defined by the spec. ### Confirm a packing option with Amazon **POST** `/fba-transport/v2024/plans/{plan}/confirm-packing-option` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | packing_option_id | string | Yes | | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Fetch packing group items from Amazon **GET** `/fba-transport/v2024/plans/{plan}/packing-group-items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan. Use the same value as the `plan` path parameter (the Conveyr plan UUID). | | packing_option_id | string | Yes | The Conveyr UUID of the packing option — i.e. the `id` field of a packing option from the packing-options response, NOT its `packing_option_id` field (which is Amazon's identifier). Passing Amazon's `packing_option_id` here will not match and the request will fail. | | packing_group_id | string | Yes | The packing group's identifier — i.e. the `id` field of an entry in the packing option's `packing_groups` array from the packing-options response. Unlike `packing_option_id`, this value is Amazon's own packing group ID (there is no separate Conveyr UUID for packing groups). | #### Expected Response Status: `200` Packing group items fetched and stored successfully. Body: no response body is defined by the spec. ### Mark a packing option as confirmed **POST** `/fba-transport/v2024/plans/{plan}/mark-packing-option-as-confirmed` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | packing_option_id | string | Yes | | #### Expected Response Status: `200` Packing option marked as confirmed successfully. Content-Type: `application/json` ```json { "message": "Packing option confirmed successfully" } ``` ### Submit box contents to Amazon Submits the plan's box contents (box groups, dimensions, weights, and items) to Amazon's Fulfillment Inbound API as packing information. The plan must have a confirmed packing option (when packing info is known) or a confirmed placement option (when packing info is unknown), and all box groups must have at least one item. Returns an operation ID that can be polled to check completion. **POST** `/fba-transport/v2024/plans/{plan}/set-packing-information` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Packing information submitted successfully. The response body contains the operation ID as a plain text string. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Reset packing information submissions Clears the packing information submission from the plan, allowing box contents to be modified and re-submitted. **POST** `/fba-transport/v2024/plans/{plan}/reset-submissions` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | #### Expected Response Status: `200` Submissions reset successfully. Content-Type: `application/json` ```json { "message": "Submissions reset" } ``` ### Generate placement options for an FBA plan Triggers an asynchronous operation to generate placement options (fulfilment centre assignments) from Amazon for the plan. Poll the returned operation ID until complete, then call GET /placement-options to retrieve the results. **POST** `/fba-transport/v2024/plans/{plan}/generate-placement-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Fetch placement options from Amazon Pulls the latest placement options from Amazon and stores them on the plan. Call this after the generate-placement-options operation completes. View the resulting options via the plan resource. **GET** `/fba-transport/v2024/plans/{plan}/placement-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | #### Expected Response Status: `200` Placement options fetched and stored on the plan successfully. Body: no response body is defined by the spec. ### Select a placement option Marks a placement option as selected locally. This does not submit anything to Amazon — call confirm-placement-option to submit the selection. **POST** `/fba-transport/v2024/plans/{plan}/select-placement-option` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | The Amazon placement option ID to select | #### Expected Response Status: `200` Placement option selected successfully. Body: no response body is defined by the spec. ### Confirm a placement option with Amazon Submits the selected placement option to Amazon asynchronously. Poll the returned operation ID until complete, then call mark-placement-option-as-confirmed to update local state. **POST** `/fba-transport/v2024/plans/{plan}/confirm-placement-option` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | The Amazon placement option ID to confirm | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Mark a placement option as confirmed Updates local state to reflect that Amazon has confirmed the placement option. Call this after the confirm-placement-option operation completes successfully. **POST** `/fba-transport/v2024/plans/{plan}/mark-placement-option-as-confirmed` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | The Amazon placement option ID to mark as confirmed | #### Expected Response Status: `200` Placement option marked as confirmed successfully. Content-Type: `application/json` ```json { "message": "Placement option confirmed successfully" } ``` ### Reset placement options for an FBA plan Clears all placement options from the plan, allowing them to be regenerated. **POST** `/fba-transport/v2024/plans/{plan}/reset-placement-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | #### Expected Response Status: `200` Placement options reset successfully. Body: no response body is defined by the spec. ### Generate delivery window options for a shipment Triggers an asynchronous operation to generate delivery window options for a specific shipment from Amazon. Poll the returned operation ID until complete, then call GET /delivery-window-options to retrieve the results. **POST** `/fba-transport/v2024/plans/{plan}/generate-delivery-window-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | The Amazon shipment ID to generate delivery windows for | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Fetch delivery window options from Amazon Pulls the latest delivery window options from Amazon for a specific shipment and stores them locally. Call this after the generate-delivery-window-options operation completes. **GET** `/fba-transport/v2024/plans/{plan}/delivery-window-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Delivery window options fetched and stored successfully. Body: no response body is defined by the spec. ### Confirm a delivery window option with Amazon Submits the selected delivery window option for a shipment to Amazon asynchronously. Poll the returned operation ID until complete, then call mark-delivery-window-option-as-confirmed. **POST** `/fba-transport/v2024/plans/{plan}/confirm-delivery-window-option` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | The Amazon shipment ID | | delivery_window_option_id | string | Yes | The Amazon delivery window option ID to confirm | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Mark a delivery window option as confirmed Updates local state to reflect that Amazon has confirmed the delivery window option. Call this after the confirm-delivery-window-option operation completes successfully. **POST** `/fba-transport/v2024/plans/{plan}/mark-delivery-window-option-as-confirmed` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | The Amazon shipment ID | | delivery_window_option_id | string | Yes | The Amazon delivery window option ID to mark as confirmed | #### Expected Response Status: `200` Delivery window option marked as confirmed successfully. Content-Type: `application/json` ```json { "message": "Delivery window option confirmed successfully" } ``` ### Generate transportation options for shipments Triggers an asynchronous operation to generate transportation options (carrier and mode selections) from Amazon for one or more shipments. Poll the returned operation ID until complete, then call GET /transportation-options to fetch the results. **POST** `/fba-transport/v2024/plans/{plan}/generate-transportation-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | The Amazon placement option ID | | shipments_dates | array | Yes | The shipments and their earliest ready-to-ship dates | | shipments_dates.*.shipment_id | string | Yes | The Amazon shipment ID | | shipments_dates.*.start_date | string | Yes | The earliest date the shipment will be ready (ISO 8601) | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Fetch transportation options from Amazon Pulls the latest transportation options from Amazon for a specific shipment and stores them locally. Call this after the generate-transportation-options operation completes. **GET** `/fba-transport/v2024/plans/{plan}/transportation-options` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Transportation options fetched and stored successfully. Content-Type: `application/json` ```json { "message": "Transportation options fetched successfully" } ``` ### Confirm transportation options with Amazon Submits the selected transportation options (carrier and mode) for one or more shipments to Amazon asynchronously. Poll the returned operation ID until complete, then call mark-transportation-option-as-confirmed. **POST** `/fba-transport/v2024/plans/{plan}/confirm-transportation-option` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | idempotency_key | string | No | Stable client key for returning the existing operation when retrying the same confirm request | | shipment_transportation_ids | array | Yes | The shipment and transportation option ID pairs to confirm | | shipment_transportation_ids.*.shipment_id | string | Yes | The Amazon shipment ID | | shipment_transportation_ids.*.transportation_option_id | string | Yes | The Amazon transportation option ID to confirm | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Mark transportation options as confirmed Updates local state to reflect that Amazon has confirmed the transportation options. Call this after the confirm-transportation-option operation completes successfully. **POST** `/fba-transport/v2024/plans/{plan}/mark-transportation-option-as-confirmed` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | | shipment_transportation_ids | array | Yes | The shipment and transportation option ID pairs to mark as confirmed | | shipment_transportation_ids.*.shipment_id | string | Yes | The Amazon shipment ID | | shipment_transportation_ids.*.transportation_option_id | string | Yes | The Amazon transportation option ID | #### Expected Response Status: `200` Transportation options marked as confirmed successfully. Content-Type: `application/json` ```json { "message": "Transportation option confirmed successfully" } ``` ### Fetch shipments for a placement option from Amazon **GET** `/fba-transport/v2024/plans/{plan}/get-shipment` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | #### Expected Response Status: `200` A successful response returning shipments Content-Type: `application/json` ```json { "data": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "shipment_id": "shipment-1", "amazon_reference_id": "AMZN123", "status": "WORKING", "shipment_confirmation_id": "FBA123", "first_availability_date": "2026-05-15T00:00:00.000000Z", "transport_mode_preference": "PARTNERED_GROUND_SMALL_PARCEL", "contact_information": { "name": "string", "email": "string", "phone_number": "string" }, "freight_information": { "freight_class": "string" }, "selected_transportation_option_id": "string", "pallets": [ { "id": "string", "length_mm": 1, "width_mm": 1, "height_mm": 1, "weight_gm": 1, "repeat": 1, "stackable": true } ], "box_groups": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "length_mm": 300, "width_mm": 200, "height_mm": 100, "weight_gm": 1000, "number_of_boxes": 1, "box_numbers": [ 1 ], "items": [ { "id": "string", "plan_item_id": "string", "quantity": 1 } ] } ], "boxes": [ { "id": "string", "box_group_id": "string", "amazon_box_id": "string", "box_number": 1 } ], "items": [ { "id": "string", "plan_item_id": "string", "shipment_id": "string", "quantity": 1 } ], "delivery_window_options": [], "transportation_options": [] } ] } ``` ### List shipment boxes **GET** `/fba-transport/v2024/plans/{plan}/list-shipment-boxes` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` A successful response returning shipment box groups Content-Type: `application/json` ```json { "data": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "length_mm": 300, "width_mm": 200, "height_mm": 100, "weight_gm": 1000, "number_of_boxes": 1, "box_numbers": [ 1 ], "items": [ { "id": "string", "plan_item_id": "string", "quantity": 1 } ] } ] } ``` ### Fetch shipment items from Amazon **GET** `/fba-transport/v2024/plans/{plan}/list-shipment-items` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Shipment items fetched and stored successfully. Body: no response body is defined by the spec. ### Update an FBA transport v2024 plan from Amazon **POST** `/fba-transport/v2024/plans/{plan}/update` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Plan updated successfully. Content-Type: `application/json` Body: no response body is defined by the spec. ### Update whether packing information is known **POST** `/fba-transport/v2024/plans/{plan}/update-packing-info-known` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | is_packing_info_known | boolean | Yes | | #### Expected Response Status: `200` Packing workflow updated successfully. Body: no response body is defined by the spec. ### Update an FBA shipment name **POST** `/fba-transport/v2024/plans/{plan}/update-shipment-name` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | shipment_id | string | Yes | | | name | string | Yes | | #### Expected Response Status: `204` Shipment name updated successfully. Body: no response body is defined by the spec. ### Change whether a plan uses 2D barcodes **POST** `/fba-transport/v2024/plans/{plan}/change-using-2d-barcodes` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | using_2d_barcodes | boolean | Yes | | #### Expected Response Status: `200` 2D barcode setting updated successfully. Body: no response body is defined by the spec. ### Set Amazon box IDs for plan boxes **GET** `/fba-transport/v2024/plans/{plan}/set-boxes-ids` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `202` Boxes were assigned and saved. Content-Type: `application/json` ```json { "message": "Boxes are assigned for the shipment." } ``` ### Create a pallet for a shipment **POST** `/fba-transport/v2024/plans/{plan}/pallets` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | | length_mm | integer | Yes | | | width_mm | integer | Yes | | | height_mm | integer | Yes | | | weight_gm | integer | Yes | | | repeat | integer | Yes | | | stackable | boolean | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Pallet created" } ``` ### Update a shipment pallet **PUT** `/fba-transport/v2024/plans/{plan}/pallets/{pallet_id}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | pallet_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | | length_mm | integer | Yes | | | width_mm | integer | Yes | | | height_mm | integer | Yes | | | weight_gm | integer | Yes | | | repeat | integer | Yes | | | stackable | boolean | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Pallet updated" } ``` ### Remove a shipment pallet **DELETE** `/fba-transport/v2024/plans/{plan}/pallets/{pallet_id}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | pallet_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Pallet removed" } ``` ### Get shipment contact information **GET** `/fba-transport/v2024/plans/{plan}/contact-information` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Contact information response. Content-Type: `application/json` Body: no response body is defined by the spec. ### Update shipment contact information **POST** `/fba-transport/v2024/plans/{plan}/update-contact-information` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | | email | string | No | | | name | string | No | | | phone_number | string | No | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Contact information set successfully" } ``` ### Get shipment freight information **GET** `/fba-transport/v2024/plans/{plan}/freight-information` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` Freight information response. Content-Type: `application/json` Body: no response body is defined by the spec. ### Update shipment freight information **POST** `/fba-transport/v2024/plans/{plan}/update-freight-information` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | | freight_class | string | No | | | amount | string | No | | | code | string | No | | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Freight information updated successfully" } ``` ### Set shipment first availability date **POST** `/fba-transport/v2024/plans/{plan}/set-first-availability-date` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | | first_availability_date | string | Yes | | #### Expected Response Status: `200` First availability date updated successfully. Body: no response body is defined by the spec. ### Set shipment transport mode preference **POST** `/fba-transport/v2024/plans/{plan}/set-transport-mode-preference` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | | transport_mode_preference | string | Yes | | #### Expected Response Status: `200` Transport mode preference updated successfully. Body: no response body is defined by the spec. ### Update small parcel tracking details **POST** `/fba-transport/v2024/plans/{plan}/update-tracking-small-details` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | shipment_id | string | Yes | | | box_tracking_ids | array | Yes | | | box_tracking_ids.*.amazon_box_id | string | Yes | | | box_tracking_ids.*.tracking_id | string | Yes | | #### Expected Response Status: `200` Small parcel tracking details updated successfully. Body: no response body is defined by the spec. ### Update LTL tracking details **POST** `/fba-transport/v2024/plans/{plan}/update-tracking-ltl-details` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | | | shipment_id | string | Yes | | | bill_of_lading_number | string | No | | | freight_bill_number | array | Yes | | #### Expected Response Status: `200` LTL tracking details updated successfully. Body: no response body is defined by the spec. ### Cancel an FBA transport plan with Amazon **POST** `/fba-transport/v2024/plans/{plan}/cancel-plan` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Operation created. The response body is the operation ID as plain text. Content-Type: `text/plain` ```json "019953ae-8047-71b6-8214-cafa0b1eff32" ``` ### Check whether canceling an FBA transport plan may incur fees **POST** `/fba-transport/v2024/plans/{plan}/cancel-plan-checker` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | plan_id | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Cancel fee warning response. Content-Type: `application/json` Body: no response body is defined by the spec. ### Mark an FBA transport plan as canceled **POST** `/fba-transport/v2024/plans/{plan}/mark-plan-as-canceled` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | #### Expected Response Status: `200` Successful response Content-Type: `application/json` ```json { "message": "Plan canceled successfully" } ``` ### Generate a pick list PDF **GET** `/fba-transport/v2024/plans/{plan}/pick-list` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` A successful response returning a generated PDF URL Content-Type: `application/json` ```json { "message": "Pick list generated", "url": "https://example.com/list.pdf" } ``` ### Generate a pack list PDF **GET** `/fba-transport/v2024/plans/{plan}/pack-list` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | plan | string | Yes | The ID of the FBA transport v2024 plan | | placement_option_id | string | Yes | | | shipment_id | string | Yes | | #### Expected Response Status: `200` A successful response returning a generated PDF URL Content-Type: `application/json` ```json { "message": "Pack list generated", "url": "https://example.com/list.pdf" } ``` ### Get an FBA transport operation Returns the current state of an async FBA transport operation. Use this to poll for completion after calling any endpoint that returns an operation ID. **GET** `/fba-transport/v2024/operations/{operation}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | operation | string | Yes | The ID of the operation | #### Expected Response Status: `200` The operation Content-Type: `application/json` ```json { "data": { "id": "019953ae-8047-71b6-8214-cafa0b1eff32", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:05Z", "channel_id": 1, "operation_id": "XlJbBi51GdqP9yfQDUQA43EI0VrQ7mJdlzfLmY", "status": "SUCCESS", "description": "setPackingInformation", "problems": null } } ``` ### Fetch an operation status update from Amazon Pulls the latest status for an operation from Amazon and updates local state. Returns the updated operation. **GET** `/fba-transport/v2024/operations/{operation}/update` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | operation | string | Yes | The ID of the operation | #### Expected Response Status: `200` The updated operation Content-Type: `application/json` ```json { "data": { "id": "019953ae-8047-71b6-8214-cafa0b1eff32", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:05Z", "channel_id": 1, "operation_id": "XlJbBi51GdqP9yfQDUQA43EI0VrQ7mJdlzfLmY", "status": "SUCCESS", "description": "setPackingInformation", "problems": [] } } ``` ### List FBA transport operations **GET** `/fba-transport/v2024/operations` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | q | string | No | Search operations by ID | | page | integer | No | The page number to retrieve (1-indexed) | | per_page | integer | No | The number of items per page | #### Expected Response Status: `200` A successful response returning the paginated list of FBA transport operations Content-Type: `application/json` ```json { "data": [ { "id": "019953ae-8047-71b6-8214-cafa0b1eff32", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:05Z", "channel_id": 1, "operation_id": "XlJbBi51GdqP9yfQDUQA43EI0VrQ7mJdlzfLmY", "status": "SUCCESS", "description": "setPackingInformation", "problems": [] } ], "total": 42, "current_page": 1, "last_page": 5, "per_page": 10, "from": 1, "to": 10, "first_page_url": "string", "last_page_url": "string", "next_page_url": "string", "prev_page_url": "string", "path": "string", "links": [] } ``` ### Fetch stored FBA item eligibility **GET** `/fba-transport/v2024/item-eligibility` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | Yes | | | asins | array | Yes | | #### Expected Response Status: `200` A successful response returning stored item eligibility records Content-Type: `application/json` ```json { "data": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "channel_id": 1, "asin": "B00ZB18SIF", "program": "INBOUND", "is_eligible": true, "ineligibility_reasons": [] } ] } ``` ### Fetch FBA item eligibility from Amazon **GET** `/fba-transport/v2024/fetch-item-eligibility` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | Yes | | | asin | string | Yes | | #### Expected Response Status: `200` A successful response returning the fetched item eligibility record Content-Type: `application/json` ```json { "data": { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "channel_id": 1, "asin": "B00ZB18SIF", "program": "INBOUND", "is_eligible": true, "ineligibility_reasons": [] } } ``` ### Fetch FBA item prep details **GET** `/fba-transport/v2024/item-prep-details` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | Yes | | | mskus | array | Yes | | | fresh | boolean | No | | #### Expected Response Status: `200` A successful response returning item prep details Content-Type: `application/json` ```json { "data": [ { "id": "019b2286-9fee-71de-9f64-154824d3aa4d", "channel_id": 1, "msku": "Mini-Porta-276810", "allOwnersConstraint": null, "labelOwnerConstraint": "SELLER", "prepOwnerConstraint": "SELLER", "prepCategory": "NONE", "prepTypes": [ "ITEM_NO_PREP" ] } ] } ``` ### Set FBA item prep details **POST** `/fba-transport/v2024/item-prep-details` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | Yes | | | prep_details | array | Yes | | | prep_details.*.msku | string | Yes | | | prep_details.*.prep_category | string | Yes | | | prep_details.*.prep_types | array | No | | #### Expected Response Status: `200` A successful response returning the operation ID or a retry message Content-Type: `application/json` ```json { "operation_id": "019953ae-8047-71b6-8214-cafa0b1eff32", "message": "Amazon returned errors that were automatically handled, please try this request again." } ``` ### List Amazon FBA inbound plans **GET** `/fba-transport/v2024/list-v2024-plans` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | warehouse_id | integer | Yes | | | status | string | No | | | pagination_token | string | No | | #### Expected Response Status: `200` A successful response returning Amazon inbound plans Content-Type: `application/json` ```json { "plans": [ { "created_at": "2026-05-14T12:00:00Z", "last_updated_at": "2026-05-14T12:30:00Z", "inbound_plan_id": "wf123", "marketplace_ids": [ "ATVPDKIKX0DER" ], "name": "Imported inbound plan", "status": "ACTIVE" } ], "pagination_token": null } ``` ### Import an Amazon FBA inbound plan **GET** `/fba-transport/v2024/import-plan` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inbound_plan_id | string | Yes | | | channel_id | string | Yes | | | warehouse_id | integer | Yes | | | create_inbound | boolean | Yes | | #### Expected Response Status: `200` A successful response returning the imported FBA transport plan Content-Type: `application/json` ```json { "plan": { "id": "plan_abc123", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z", "name": "string", "outbound_shipment_id": 1, "channel_id": 1, "inbound_plan_id": "inboundPlanId-abc123", "create_plan_operation_id": "string", "is_canceled": true, "using_2d_barcodes": true, "status": "string", "marketplace": { "identifier": "ATVPDKIKX0DER", "country": "United States" }, "items": [ { "id": "string", "msku": "string", "fnsku": "string", "asin": "string", "quantity": 1, "label_owner": "string", "prep_owner": "string", "expiration": "string", "manufacturing_lot_code": "string", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z" } ], "packing_options": [], "box_groups": [], "placement_options": [], "is_packing_information_set": true, "isPackingInfoKnown": true } } ``` --- ## Workflow Create an Amazon FBA inbound transport plan and drive it through to labels ### Overview The FBA workflow creates an Amazon inbound plan from an outbound shipment, submits packing information, lets Amazon choose where the inventory is sent, confirms transportation, then requests labels. Most stages are asynchronous on Amazon's side and follow the same three-part pattern described below. The plan object is the source of truth between calls. After every operation completes, reload the plan with `GET /plans/{plan_id}` and read the IDs you need from the refreshed response rather than reusing IDs from an earlier call. ### The async-then-commit pattern This is the single most important thing to understand. Almost every stage is **three calls, not one**: 1. **Dispatch** — a `generate-*` or `confirm-*` call that sends an async request to Amazon and returns an **operation id**. 2. **Poll** — drive that operation to `SUCCESS` with `GET /operations/{id}/update`. 3. **Commit** — a `select-*` or `mark-*-as-confirmed` call that records the confirmation on the plan. **An operation reaching `SUCCESS` does not mean the step is confirmed.** `SUCCESS` only means Amazon finished the async work for the dispatch call. The selection is not recorded until you call the matching `select-*` / `mark-*-as-confirmed` step. If you skip the commit step, the operation still succeeds, but the option stays `OFFERED`, `is_packing_information_set` stays `false`, and the next step rejects with errors like “No placement option has confirmed” or “Packing information submission is required.” The `mark-*-as-confirmed` and `select-*` calls are local: they do not call Amazon, they record the confirmation (and, for transportation, release a lock). Always poll the operation, *not* the plan — the plan's `updated_at` does not move while an operation is running, which is not a sign of failure. **Dispatch, poll, commit** ``` # 1. Dispatch — returns an operation id POST /api/fba-transport/v2024/plans/{plan_id}/confirm-placement-option => { "operation_id": "019953ae-..." } # 2. Poll the operation until it is SUCCESS (not the plan) GET /api/fba-transport/v2024/operations/{operation_id}/update => { "status": "IN_PROGRESS" } # keep polling => { "status": "SUCCESS" } # Amazon finished the async work # 3. Commit — record the confirmation in your plan POST /api/fba-transport/v2024/plans/{plan_id}/mark-placement-option-as-confirmed # Only now is the placement option actually confirmed. Reload the plan. GET /api/fba-transport/v2024/plans/{plan_id} ``` ### Two kinds of IDs Every option, group, and box in the plan response carries two identifiers: **our internal `id`** (a UUID) and **Amazon's id** (for example `packing_option_id`, `placement_option_id`, or a box's `amazon_box_id`). Sending the wrong one is a common cause of “not found / is null” errors. Which id each endpoint expects: | Endpoint | Send | | --- | --- | | confirm-packing-option, mark-packing-option-as-confirmed | Amazon `packing_option_id` | | packing-group-items | the option's and group's internal `id` (the plan response `id` field) — **not** Amazon's id | | add-carton-request-to-submission | `packing_group_ids`: array of each packing group's `id` from the plan response | | select/confirm/mark placement | Amazon `placement_option_id` | | confirm/mark transportation | `shipment_transportation_ids`: array of `{ shipment_id, transportation_option_id }` | | update-tracking-small-details | the box's `amazon_box_id` (the `FBA…` value) — **not** the internal box `id` | **Both ids appear on the plan** ```json GET /api/fba-transport/v2024/plans/{plan_id} { "packing_options": [ { "id": "0c8e3b1a-...", // <-- OUR internal id (a UUID) "packing_option_id": "po8e61...", // <-- AMAZON's id "status": "OFFERED", "packing_groups": [ { "id": "pg1d2c3b4-..." } // packing group: use this "id" ] } ], "placement_options": [ { "id": "...", "placement_option_id": "pl4eb6..." } ] } ``` ### Prerequisites and preflight You need an outbound shipment, an Amazon channel, and one or more merchant SKUs with quantities. The SKUs must exist on the Amazon channel and be eligible for inbound shipment. Check eligibility and prep details before creating the plan — the cached endpoints avoid a live Amazon fetch, while `fetch-item-eligibility` asks Amazon for the latest eligibility of one ASIN. **Optional preflight checks** ``` GET /api/fba-transport/v2024/item-eligibility?channel_id={channel_id}&asins[]={asin} GET /api/fba-transport/v2024/fetch-item-eligibility?channel_id={channel_id}&asin={asin} GET /api/fba-transport/v2024/item-prep-details?channel_id={channel_id}&mskus[]={msku} ``` ### Create the plan Create the plan from the outbound shipment. `createInboundPlan` accepts only `msku`, `quantity`, `prep_owner`, `label_owner`, and `expiration`. Amazon does not take an FNSKU or ASIN here, so a freshly created plan item always has `fnsku: null` and `asin: null`. That is expected — see [When FNSKUs get stamped](#fnsku) below. If creation rejects an item (for example brand approval, `FBA_INB_0021`), the reason is on the create operation's `problems` array, not on the plan items — see [Reading per-item errors](#errors). **Create plan** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "outbound_shipment_id": 5, "channel_id": 1, "destination_marketplace": "ATVPDKIKX0DER", "items": [ { "msku": "Mini-Porta-276810", "quantity": 40, "label_owner": "SELLER", "prep_owner": "SELLER", "expiration": null, "manufacturing_lot_code": null } ] }' ``` ### Choose the packing workflow Set whether packing information is known before placement with `update-packing-info-known`. Use **pack first** for small parcel and any flow where box contents are known up front. Use **pack later** when placement must be confirmed before cartons are finalized, most commonly for LTL. Pack later does not support small parcel in the current workflow. If `generate-packing-options` returns `SUCCESS` but `packing_options` stays empty, Amazon found no valid packing arrangement for the plan. Re-firing will not change it. This is almost always an item-level eligibility or compliance problem (or the plan errored), so check item eligibility and the create operation's problems rather than retrying. #### Pack first **Pack first sequence** ``` # Packing (operation -> SUCCESS -> commit at each confirm) POST update-packing-info-known # is_packing_information_known = true POST generate-packing-options # -> operation, poll to SUCCESS GET packing-options GET packing-group-items # stamps FNSKU/ASIN (use internal ids) POST confirm-packing-option # -> operation, poll to SUCCESS POST mark-packing-option-as-confirmed # COMMIT (local) # Box contents POST box-groups POST box-groups/{box_group_id}/set-box-quantity POST box-groups/{box_group_id}/items POST set-packing-information # -> operation, poll to SUCCESS POST add-carton-request-to-submission # COMMIT box contents (packing_group_ids) # Placement POST generate-placement-options # -> operation, poll to SUCCESS GET placement-options POST select-placement-option POST confirm-placement-option # -> operation, poll to SUCCESS POST mark-placement-option-as-confirmed # COMMIT (local) GET set-boxes-ids # assign Amazon box ids to the shipment ``` #### Pack later **Pack later sequence** ``` POST update-packing-info-known # is_packing_information_known = false POST generate-placement-options # -> operation, poll to SUCCESS GET placement-options POST select-placement-option POST confirm-placement-option # -> operation, poll to SUCCESS POST mark-placement-option-as-confirmed # COMMIT (local) GET get-shipment GET list-shipment-boxes POST box-groups POST box-groups/{box_group_id}/items POST set-packing-information # -> operation, poll to SUCCESS POST add-carton-request-to-submission # COMMIT box contents GET set-boxes-ids ``` **Confirm packing option (Amazon packing_option_id)** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/confirm-packing-option \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "packing_option_id": "packing-option-1" }' ``` **Commit: mark packing option as confirmed** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/mark-packing-option-as-confirmed \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "packing_option_id": "packing-option-1" }' ``` ### When FNSKUs get stamped Plan items are created with `fnsku: null` and `asin: null`. Nothing back-fills them on a timer, and `set-packing-information` reaching `SUCCESS` does not stamp them. They are written onto the plan items only when you read the items back from Amazon through `packing-group-items` (before placement) or `list-shipment-items` (after placement). That same fetch is what assigns Amazon box IDs downstream, so if the FNSKU never lands, the box never gets an `amazon_box_id` and tracking and labels both fail with “one or more items are missing an FNSKU.” **The `packing-group-items` query parameters are misleadingly named.** `packing_option_id` and `packing_group_id` here both expect the internal `id` field from the plan response, not Amazon's `packing_option_id`. Sending Amazon's id returns “Failed to fetch packing group for plan. Packing option is null.” and the FNSKU never stamps. **Stamp FNSKU/ASIN with the internal ids** ``` # packing_option_id and packing_group_id here are the "id" fields # from the plan response (our internal UUIDs), NOT Amazon's packing_option_id. GET /api/fba-transport/v2024/plans/{plan_id}/packing-group-items \ ?packing_option_id={packing_option.id} \ &packing_group_id={packing_group.id} # Then re-read the plan; fnsku and asin are now populated on the items. GET /api/fba-transport/v2024/plans/{plan_id} ``` ### Submit box contents A box group describes one package size and weight plus the associated Amazon packing group or shipment. Create box groups, set quantities, and add plan items, then call `set-packing-information` and drive its operation to `SUCCESS`. Commit the box contents with `add-carton-request-to-submission`, passing each packing group's `id`. There is **no** `mark-packing-information-as-confirmed` route. `add-carton-request-to-submission` is the call that finalizes packing information. **Set packing information** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/set-packing-information \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad" }' ``` **Commit box contents (packing_group_ids = plan response ids)** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/add-carton-request-to-submission \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "packing_group_ids": [ "packing-group-1" ] }' ``` ### Select and confirm placement Placement options describe how Amazon wants the plan split across fulfillment centers and what fees or discounts apply. Generate options, select one, then confirm it (dispatch, poll, commit). If you regenerate or re-pull placement options after confirming, the confirmation is cleared along with any delivery-window and transportation selections, so do not regenerate placement once you have moved past it. After placement is confirmed, call `set-boxes-ids`. It requires a confirmed placement and assigns Amazon box IDs to the shipment. Until it runs, the boxes have contents on our side but are not assigned on Amazon, and `confirm-transportation-option` and `request-box-labels` reject with “Boxes are assigned incorrectly for the shipment.” Amazon assigns the per-box `amazon_box_id` (the `FBA…` value) shortly after placement is confirmed, and `set-boxes-ids` is what reads it from Amazon and stamps it onto the box. **Read the stamped id from `get-shipment`, in the `boxes[].amazon_box_id` field** (or nested under `placement_options[].shipments[].boxes[]` on the plan response). Do **not** poll `list-shipment-boxes` for it: that endpoint returns box-group geometry and contents only and has no box-id field, so the id never appears there. If `boxes[]` is empty on `get-shipment`, `set-boxes-ids` has not run since placement was confirmed. **Select placement option** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/select-placement-option \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "placement_option_id": "placementOptionId-abc123" }' ``` **Confirm placement option** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/confirm-placement-option \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "placement_option_id": "placementOptionId-abc123" }' ``` **Commit: mark placement option as confirmed** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/mark-placement-option-as-confirmed \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "placement_option_id": "placementOptionId-abc123" }' ``` **Assign Amazon box ids** ```bash curl -G https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/set-boxes-ids \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" ``` ### Delivery window (non-partnered) When a transportation option lists `PRECONDITIONS: CONFIRMED_DELIVERY_WINDOW` (typical for non-partnered shipments), confirm a delivery window first. Set the first availability date and transport mode, generate windows, then confirm and commit the chosen window. The generate-delivery-window operation can sit at `IN_PROGRESS` even after the windows are listable — this is Amazon eventual consistency. It is safe to pick from the listed options; what matters is that the `confirm-delivery-window-option` operation reaches `SUCCESS`, then run the mark step. **Delivery window sequence** ``` # Per shipment, for non-partnered (and where the transportation # option lists PRECONDITIONS: CONFIRMED_DELIVERY_WINDOW) POST set-first-availability-date POST set-transport-mode-preference POST generate-delivery-window-options # -> operation, poll to SUCCESS GET delivery-window-options POST confirm-delivery-window-option # -> operation, poll to SUCCESS POST mark-delivery-window-option-as-confirmed # COMMIT (local) ``` **Confirm delivery window option** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/confirm-delivery-window-option \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "shipment_id": "shipmentId-abc123", "delivery_window_option_id": "deliveryWindowOptionId-abc123" }' ``` **Commit: mark delivery window option as confirmed** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/mark-delivery-window-option-as-confirmed \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "shipment_id": "shipmentId-abc123", "delivery_window_option_id": "deliveryWindowOptionId-abc123" }' ``` ### Confirm transportation Generate transportation options after placement is confirmed and boxes are assigned. Confirm one option per shipment (`shipment_transportation_ids`), drive the operation to `SUCCESS`, then call `mark-transportation-option-as-confirmed`. Transportation options can expire; regenerate if they are more than about 15 minutes old. **The “ConfirmTransportationOptions already in progress” lock.** `confirm-transportation-option` takes a lock so a second confirm cannot race it. Driving the operation to `SUCCESS` does **not** release it — only `mark-transportation-option-as-confirmed` does. Call `confirm-transportation-option` once per attempt and follow it with the mark step. Re-firing confirm before marking just bounces off the lock, so the option never commits and downstream calls (including `update-tracking-small-details`) fail. **`generate-transportation-options` takes the same lock.** It holds the lock until you drive the *generate* operation to `SUCCESS` with `GET /operations/{id}/update` (or until it expires a few minutes later). So if you call `confirm-transportation-option` after generating without first polling the generate operation to completion, confirm returns “already in progress” with no operation id — even though you never re-fired confirm. Always drive the generate operation to `SUCCESS` before confirming, and do not regenerate transportation between the confirm and mark steps. **Transportation sequence** ``` # Placement must already be confirmed (mark-placement-option-as-confirmed) GET set-boxes-ids # boxes must be assigned first POST generate-transportation-options # -> operation, poll to SUCCESS GET transportation-options POST confirm-transportation-option # -> operation, poll to SUCCESS POST mark-transportation-option-as-confirmed # COMMIT + releases the lock ``` **Generate transportation options** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/generate-transportation-options \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "placement_option_id": "placementOptionId-abc123", "shipments_dates": [ { "shipment_id": "shipmentId-abc123", "start_date": "2024-06-01" } ] }' ``` **Confirm transportation option** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/confirm-transportation-option \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "idempotency_key": "confirm-transportation:FbaTransport_ConfirmTransportationOptions_019953ae", "shipment_transportation_ids": [ { "shipment_id": "shipmentId-abc123", "transportation_option_id": "transportationOptionId-abc123" } ] }' ``` **Commit: mark transportation option as confirmed** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/mark-transportation-option-as-confirmed \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "shipment_transportation_ids": [ { "shipment_id": "shipmentId-abc123", "transportation_option_id": "transportationOptionId-abc123" } ] }' ``` ### Hazmat and non-partnered shipping For dangerous goods, Amazon does not quote a partnered carrier, so `generate-transportation-options` can run for a couple of minutes and return **zero partnered options**. That is expected. The signal to go non-partnered is the option set coming back entirely as `USE_YOUR_OWN_CARRIER` with no partnered option present; confirm the own-carrier option (for example Deutsche Post DHL), then write tracking. `update-tracking-small-details` requires a **confirmed** non-PCP (own-carrier) transportation option — otherwise Amazon returns “can only be processed for shipments that have confirmed a non-PCP transportation option.” Send the box's `amazon_box_id` (the `FBA…` value), not the internal box id. Read that id from `get-shipment` (`boxes[].amazon_box_id`). If it is empty, run `set-boxes-ids` (it needs a confirmed placement) to stamp it, then re-read `get-shipment`. **Small parcel tracking (amazon_box_id)** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/update-tracking-small-details \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad", "shipment_id": "shipment-1", "box_tracking_ids": [ { "amazon_box_id": "FBA1U000001", "tracking_id": "1Z999AA10123456784" } ] }' ``` ### 2D barcodes and box labels A plan can use Amazon 2D barcodes for box content: `set-packing-information` sends `contentInformationSource: BARCODE_2D` for each box. On a 2D-barcode plan the 4x6 box label is generated by PrepBusiness from the box's FNSKU and contents rather than requested from Amazon, so `request-box-labels` produces the label without an Amazon-assigned box id. Every item in the box must have a stamped FNSKU, or the call rejects with “one or more items are missing an FNSKU.” `set-boxes-ids` is a single `GET` with no body and no operation to poll — the `202` only means it finished. It matches the boxes Amazon has returned to your plan boxes and stamps each `amazon_box_id` onto the box; it does not create boxes on Amazon. Once placement is confirmed, run `set-boxes-ids`, then read the stamped id from `get-shipment` (`boxes[].amazon_box_id`), not from `list-shipment-boxes`. ### Request labels and paperwork Request labels only after transportation is confirmed (and, for non-partnered, after tracking is saved). FNSKUs must already be stamped or box labels reject. Labels generate asynchronously, so the first poll of the labels endpoint usually returns nothing. **Label sequence** ``` # Non-partnered: write tracking BEFORE requesting box labels POST update-tracking-small-details # -> operation, poll to SUCCESS POST request-box-labels GET labels?shipment_id={shipment_id} # poll until the 4x6 box label is ready # Partnered small parcel POST request-package-labels GET labels?shipment_id={shipment_id} POST labels/{label_id}/resize-to-4x6 # optional 4x6 resize # LTL POST request-pallet-labels POST request-bill-of-lading ``` **Request package labels** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/request-package-labels \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "shipment_id": "shipment-1" }' ``` ### Reading per-item errors When a plan will not progress, the per-item reasons the dashboard shows are **not** on `GET /plans/{plan_id}`. There are two sources. Item eligibility, approval, and compliance (for example “Approval is required before this item can be sent”) come from the eligibility endpoints, keyed by ASIN, in `ineligibilityReasons`. Rejections from plan creation come from the create-plan operation's `problems` array, with the SKU or FNSKU inside the message and details. **Where per-item errors live** ``` # 1. Item eligibility / approval / compliance (keyed by ASIN) GET /api/fba-transport/v2024/fetch-item-eligibility?channel_id=...&asin=... => { "asin": "...", "isEligible": false, "ineligibilityReasons": ["FBA_INB_0021 ..."] } # 2. Plan-creation rejections live on the create-plan operation, not the plan GET /api/fba-transport/v2024/operations/{create_operation_id} => { "status": "...", "problems": [ { "code": "...", "message": "...", "details": "...", "severity": "..." } ] } ``` ### Cancel a plan Canceling is its own dispatch-poll-commit flow. Run `cancel-plan-checker` first for warnings (for example a confirmed partnered carrier), then `cancel-plan`, drive its operation to `SUCCESS`, then `mark-plan-as-canceled`. The plan stays `ACTIVE` until the mark step sets its status to voided locally — `cancel-plan` succeeding on its own does not flip `is_canceled`. **Cancel sequence** ``` POST cancel-plan-checker # returns warnings (e.g. confirmed partnered carrier) POST cancel-plan # -> operation, poll to SUCCESS POST mark-plan-as-canceled # COMMIT: sets status = Voided locally ``` **Check before canceling** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/cancel-plan-checker \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad" }' ``` **Cancel plan** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/cancel-plan \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{ "plan_id": "019953ae-7a0d-7342-956a-881dcdbe42ad" }' ``` **Commit: mark plan as canceled** ```bash curl -X POST https://YOUR_DOMAIN/api/fba-transport/v2024/plans/{plan}/mark-plan-as-canceled \ -H "Authorization: Bearer {token}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{}' ``` ### Troubleshooting | Symptom | Cause and fix | | --- | --- | | Operation `SUCCESS` but option stays `OFFERED` / `is_packing_information_set` stays false | The commit step was skipped. Call the matching `select-*` / `mark-*-as-confirmed` (or `add-carton-request-to-submission` for packing info). | | “Failed to fetch packing group… Packing option is null” | Wrong id on `packing-group-items`. Send the internal `id` for the option and group, not Amazon's `packing_option_id`. | | `fnsku`/`asin` stay null on the plan item | Call `packing-group-items` (or `list-shipment-items`) with the correct ids; nothing back-fills on a timer. | | “Boxes are assigned incorrectly for the shipment” | Boxes not assigned on Amazon. Confirm placement, then `GET set-boxes-ids`, then retry. | | No `amazon_box_id` on the box | Boxes only carry an `amazon_box_id` after `set-boxes-ids` runs (it needs a confirmed placement). Read it from `get-shipment` (`boxes[].amazon_box_id`), not `list-shipment-boxes`, which never returns the box id. | | “ConfirmTransportationOptions already in progress” (no operation id returned) | The lock is held. Either you re-fired confirm without marking, or `generate-transportation-options` still holds it because its operation was not driven to `SUCCESS`. Drive the generate operation to `SUCCESS` via `GET /operations/{id}/update`, then confirm once and call the mark step. | | “can only be processed for shipments that have confirmed a non-PCP transportation option” | Transportation never committed. Run `confirm-transportation-option` then `mark-transportation-option-as-confirmed` before tracking. | | “one or more items are missing an FNSKU” | FNSKU not stamped yet. Stamp it via `packing-group-items`, confirm the box has an `amazon_box_id`, then request labels. | | `generate-packing-options` SUCCESS with 0 options | Amazon found no valid arrangement (usually item eligibility/compliance). Check eligibility and the create operation's problems; do not re-fire. | | Plan stays `ACTIVE` after cancel-plan SUCCESS | Call `mark-plan-as-canceled` to void it locally. | ### Recovery and updates Use `POST /plans/{plan_id}/update` to pull the latest Amazon state. Use reset endpoints (`reset-placement-options`, `reset-submissions`) only when intentionally backing up to an earlier stage, because later selections or submissions are cleared. If Amazon reports placement options were generated in Seller Central, regenerate them through the API before continuing. --- ## Orders Viewing and managing orders ### List orders **GET** `/orders` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | fulfillable | boolean | No | Filter to only return fulfillable orders | #### Expected Response Status: `200` A successful response returning the list of orders Content-Type: `application/json` ```json { "orders": [ { "id": 1, "created_at": "2022-03-22T13:02:07.000000Z", "updated_at": "2022-03-22T13:02:07.000000Z", "customer_id": 1, "order_id": "AYV-411841-64", "channel_id": 1, "channel_order_id": "CGZ-211973-62", "order_date": "2022-03-19 09:02:06", "ship_by": "2022-03-23 09:02:06", "arrive_by": "2022-03-25 09:02:06", "status": "pending", "should_fulfill": true, "order_items_count": 1, "order_items": [], "customer": { "id": 1, "name": "Paucek, Nicolas and Kihn" } } ] } ``` ### Upload orders **POST** `/orders/upload` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | channel_id | integer | No | The ID of the channel to upload orders for | | orders | array | Yes | The list of orders to upload | #### Expected Response Status: `200` A successful response after uploading the orders Content-Type: `application/json` ```json { "message": "Orders uploaded" } ``` ### Get an order **GET** `/orders/{order}` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | order | integer | Yes | The ID of the order | #### Expected Response Status: `200` A successful response returning the order with its relations Content-Type: `application/json` ```json { "order": { "id": 8, "created_at": "2022-09-29T20:51:03.000000Z", "updated_at": "2022-10-05T00:41:39.000000Z", "customer_id": 8, "shipping_address_id": 11, "billing_address_id": 11, "order_id": "ANX-352231-61", "channel_id": 1, "channel_order_id": "CWM-286025-86", "order_date": "2022-09-28 16:51:03", "ship_by": "2022-09-30 16:51:03", "arrive_by": "2022-10-04 16:51:03", "status": "shipped", "should_fulfill": true, "order_items": [], "customer": null, "shipping_address": null, "packages": [], "attachments": [], "tracking_numbers": [] }, "fulfillment_requests": [] } ``` ### Upload a shipping label for an order **POST** `/orders/{order}/uploadShippingLabel` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | order | integer | Yes | The ID of the order | #### Expected Response Status: `201` A successful response after uploading the shipping label Content-Type: `application/json` ```json {} ``` ### Mark an order as shipped **POST** `/orders/{order}/markAsShipped` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | order | integer | Yes | The ID of the order | | tracking_number | string | No | The tracking number for the shipment | | carrier | string | No | The carrier for the shipment | | fulfillment_request_id | string | No | The ID of the fulfillment request | #### Expected Response Status: `200` A successful response after marking the order as shipped Content-Type: `application/json` ```json { "message": "Order marked as shipped" } ``` --- ## Services Viewing and managing company services ### List company services **GET** `/services` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | type | array | No | Filter services by type | | archived | boolean | No | Filter to only return archived services | #### Expected Response Status: `200` A successful response returning the list of company services Content-Type: `application/json` ```json { "services": [ { "id": 1, "created_at": "2024-05-09T13:22:14.000000Z", "updated_at": "2024-05-09T13:22:14.000000Z", "name": "Extra Poly Bags (1.5mm)", "type": "outbound_shipment_item", "unit": "bag", "when_to_charge": "attached", "charge": "0.1500", "advanced_options": null, "service_provider_id": 1, "price_records": [], "archived_at": null, "deleted_at": null } ] } ``` --- ## Warehouses Viewing and managing warehouses ### List warehouses **GET** `/warehouses` #### Expected Response Status: `200` A successful response returning the list of warehouses Content-Type: `application/json` ```json { "data": [ { "id": 1, "uuid": "0197e188-5d70-8010-bf60-252ed9687632", "name": "AL Warehouse", "service_provider_id": 60983, "default_address": { "id": 1, "warehouse_id": 1, "address_line_1": "1300 Montgomery Highway", "address_line_2": "Suite 368", "address_line_3": null, "city": "Vestavia Hills", "state_province": "AL", "postal_code": "35216-5112", "country_code": "US", "phone_number": "2312312312", "is_residential": false }, "addresses": [ { "id": 1, "warehouse_id": 1, "address_line_1": "1300 Montgomery Highway", "address_line_2": "Suite 368", "address_line_3": null, "city": "Vestavia Hills", "state_province": "AL", "postal_code": "35216-5112", "country_code": "US", "phone_number": "2312312312", "is_residential": false } ] } ] } ``` --- ## Service Providers Viewing the service providers a merchant is connected to ### List service providers Returns every service provider the selected merchant is connected to. The merchant is taken from the `X-Selected-Client-Id` header; no service provider header is required. **GET** `/serviceProviders` #### Expected Response Status: `200` A successful response returning the list of connected service providers Content-Type: `application/json` ```json { "data": [ { "id": 1, "uuid": "01930f3e-4a3e-7c1e-9a2b-2b6f0f4e8a11", "url": "https://acmeprep.prepbusiness.com", "logo_file": null, "favicon_file": null, "support_email": "support@acmeprep.com", "name": "ACME Prep", "currency": "USD", "available_permissions": [ "createOutboundShipment" ] } ] } ``` --- ## Labels Generating and downloading FNSKU and barcode labels ### Request FNSKU labels Submits a request to generate FNSKU labels. Labels are generated asynchronously and will be available for download once processing is complete. **POST** `/labels/fnsku` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | labels | array