{
  "info": {
    "_postman_id": "58a8d3ee-25b4-5230-93a8-488960034245",
    "name": "Cru Trading API v1",
    "description": "The Cru partner trading API as implemented: Cru's bid and offer books, the caller's own bids, offers, portfolio and trades, and the writes that trade.\n\nEvery response is one envelope: status (OK or ERROR), message (for people, never branch on it), meta (version, timestamp, request_id, and pagination on paged lists) and data, with errors[] on a failure. Branch on the HTTP status and errors[].code. Paged lists take limit and offset and say meta.pagination.has_more.\n\nA partner credential (CLIENT-KEY and CLIENT-SECRET headers) writes at once and must send a reference, its idempotency key: a retry with the same reference never acts twice. A connected app (OAuth 2.0 bearer token) has its writes staged: the write answers 202 with a confirmation, and nothing happens until POST /confirmations/{code}.\n\nAmounts are plain numbers in the market's currency (1200.5 is 1,200.50), never minor units. Fields listed with x-extensible-enum may gain values: treat an unknown one as unknown, not as an error. New fields may appear in any response.\n\nGenerated from openapi-v1-implemented.yaml (version 1.0.0). Set clientKey and clientSecret, or accessToken, then run a folder top to bottom: lists save the ids the requests after them use.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Account",
      "item": [
        {
          "name": "Test authentication",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "ping"
              ]
            },
            "description": "Scope: `meta:read`.\n\nConfirm that your credentials work and see the account, market, currency, permissions and expiry they carry.\n\n**A simple first request.** This authenticated check returns your credential details without exposing any trading data."
          }
        }
      ]
    },
    {
      "name": "Warehouses",
      "item": [
        {
          "name": "List warehouses",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouses",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouses"
              ]
            },
            "description": "Scope: `meta:read`.\n\nThe five Cru warehouses wine can be delivered into: codes, addresses, bond references, delivery instructions, and whether your inbond wine sells through each.\n\n**The codes every other endpoint uses.** A bid’s deliverable_warehouses, an offer’s warehouse_code and the warehouse.deliverable_warehouse_code of a listing or a portfolio line all use these five codes, and so does the warehouse.current_location_code of wine stored in one. Warehouses outside Cru, where your wine may be stored, are GET /warehouses/inbond: an inbond_address_id is never a warehouse_code."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.warehouses?.[0]?.code !== undefined) pm.collectionVariables.set('warehouseCode', String(body?.data?.warehouses?.[0]?.code));"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve a warehouse",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouses/{{warehouseCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouses",
                "{{warehouseCode}}"
              ]
            },
            "description": "Scope: `meta:read`.\n\nOne Cru warehouse by its code, such as UK_DRAK: name, market, address, bond references, delivery instructions, and whether your inbond wine sells through it."
          }
        },
        {
          "name": "List inbond warehouses",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouses/inbond",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouses",
                "inbond"
              ]
            },
            "description": "Scope: `meta:read`.\n\nWarehouses outside Cru where your wine may be stored, by inbond_address_id: where wine held outside Cru is now, and what an inbond address points at.\n\n**Not Cru’s own warehouses.** This is the Cru website’s “Where is it now?” list. Your listings and portfolio lines in one carry IB_ and its inbond_address_id, such as IB_20, as warehouse.current_location_code. The five Cru warehouses wine is delivered into are GET /warehouses, by warehouse_code: an inbond_address_id is never a warehouse_code."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.inbond_warehouses?.[0]?.inbond_address_id !== undefined) pm.collectionVariables.set('inbondWarehouseId', String(body?.data?.inbond_warehouses?.[0]?.inbond_address_id));"
                ]
              }
            }
          ]
        },
        {
          "name": "Suggest an inbond warehouse",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouses/inbond",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouses",
                "inbond"
              ]
            },
            "description": "Scope: `warehouses:suggest`.\n\nSuggest a warehouse outside Cru that GET /warehouses/inbond does not list. Until Cru approves it, only you see it and can use its inbond_address_id.\n\n**Only with warehouses:suggest, which Cru grants.** A suggestion adds to the list every customer picks from, so Cru grants warehouses:suggest itself, on a partner credential, and never to a connected app: ask Cru to enable it. Without it, the customer emails customerservice@cruworldwine.com and Cru adds the warehouse, as the Cru website says.\n\n**Check the list first.** A warehouse Cru already lists, or one you already suggested — the same name in the same country, ignoring case and punctuation — is refused with its inbond_address_id. Five can wait for Cru at a time.\n\n**Yours alone until Cru approves it.** It is saved hidden. Until Cru approves it, it is in your GET /warehouses/inbond with pending true, and its inbond_address_id works for you — for wine held outside Cru, or an inbond address — and nobody else. To save an inbond address there, give its street, city and postcode.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"name\": \"Example Bonded Warehouse\",\n  \"country\": \"GB\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Retrieve an inbond warehouse",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouses/inbond/{{inbondWarehouseId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouses",
                "inbond",
                "{{inbondWarehouseId}}"
              ]
            },
            "description": "Scope: `meta:read`.\n\nOne inbond warehouse by its inbond_address_id: its name, company, address, phone, London City Bond site code, and whether it is bonded."
          }
        }
      ]
    },
    {
      "name": "Reference data",
      "item": [
        {
          "name": "Search wines",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/wines?q=margaux",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "wines"
              ],
              "query": [
                {
                  "key": "q",
                  "value": "margaux",
                  "description": "Words from the wine name, such as “Petrus Pomerol”: one to six words of two or more characters.",
                  "disabled": false
                },
                {
                  "key": "vintage",
                  "value": "",
                  "description": "Only this vintage.",
                  "disabled": true
                },
                {
                  "key": "pack_size",
                  "value": "",
                  "description": "Only this pack, written as bottles x size: 12x75cl, 6x150cl.",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "25",
                  "description": "Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of wines to skip.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `wines:read`.\n\nFind wines by name and get their LWIN18 codes, with producer, region, pack size, product page, Cru’s market price and the best bids and offers.\n\n**Start here to find an LWIN18.** Every other endpoint identifies a wine by its LWIN18. This searches the way the Cru website does, best match first.\n\n**No total, and at most 100 matches.** meta.pagination has has_more but no total, and the search considers its 100 best matches: paging past them finds nothing more. Narrow the words, vintage or pack instead.\n\n**Bids and offers come with market:read.** A credential that also holds market:read gets each wine’s best five bids and five offers, from the books rather than the search. With wines:read alone, the wine comes without those two keys."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.wines?.[0]?.lwin18 !== undefined) pm.collectionVariables.set('lwin18', String(body?.data?.wines?.[0]?.lwin18));"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve a wine",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/wines/{{lwin18}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "wines",
                "{{lwin18}}"
              ]
            },
            "description": "Scope: `wines:read`.\n\nOne wine by LWIN18: producer, country, region, critic score, drinking window, market price, last trade, and every bid and offer on it.\n\n**Every level of both books.** With market:read as well as wines:read, the wine carries all its bids and offers — empty lists when it has none. The wine is returned either way."
          }
        }
      ]
    },
    {
      "name": "Market data",
      "item": [
        {
          "name": "List the market",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "100",
                  "description": "Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of wines to skip.",
                  "disabled": true
                },
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated 18-digit LWIN18 codes. One that is not 18 digits is refused with VALIDATION_INVALID_VALUE.",
                  "disabled": true
                },
                {
                  "key": "depth",
                  "value": "",
                  "description": "How many bids and how many offers to return per wine, best first: bids in book order, offers cheapest first. Omit it for every level. Default: every level.",
                  "disabled": true
                },
                {
                  "key": "include_market_price",
                  "value": "false",
                  "description": "Add market_price — Cru’s market price for the wine, as a number — to each wine.",
                  "disabled": true
                },
                {
                  "key": "include_last_trade",
                  "value": "false",
                  "description": "Add last_trade — the last traded price and when — to each wine.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `market:read`.\n\nBoth sides of Cru’s market in one call: every wine with a bid or an offer, each with its bids and its offers.\n\n**Both books, one entry per wine.** Bids are net — what a seller receives. Offers are gross — what a buyer pays. They are the same objects as /market/bids and /market/offers, read from the same books.\n\n**Either side can be empty.** A wine is listed when it has a bid or an offer, so one of its two lists is often empty. Wines come by LWIN18, ascending, and pagination counts wines."
          }
        },
        {
          "name": "Retrieve the market for one wine",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/wines/{{lwin18}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "wines",
                "{{lwin18}}"
              ],
              "query": [
                {
                  "key": "depth",
                  "value": "",
                  "description": "How many bids and how many offers to return per wine, best first: bids in book order, offers cheapest first. Omit it for every level. Default: every level.",
                  "disabled": true
                },
                {
                  "key": "include_market_price",
                  "value": "false",
                  "description": "Add market_price — Cru’s market price for the wine, as a number — to each wine.",
                  "disabled": true
                },
                {
                  "key": "include_last_trade",
                  "value": "false",
                  "description": "Add last_trade — the last traded price and when — to each wine.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `market:read`.\n\nBoth sides of the market on one wine, by LWIN18: its bids and its offers in one object, without paging.\n\n**One entry of GET /market.** Bids are net — what a seller receives. Offers are gross — what a buyer pays. To filter either side by price or stock, use the wine’s /bids or /offers instead.\n\n**An empty side is an empty list.** A wine Cru knows is always described, even with nothing on either side: bids and offers are then empty lists. Only a wine Cru does not know is NOT_FOUND / 404."
          }
        },
        {
          "name": "List market bids",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/bids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "bids"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "100",
                  "description": "Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of wines to skip.",
                  "disabled": true
                },
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated LWIN18 codes. The books do not check the format, so a code that is not an LWIN18 simply matches nothing.",
                  "disabled": true
                },
                {
                  "key": "wine_name",
                  "value": "",
                  "description": "Only wines whose name contains every word given, such as “Lafite 2010”. One to six words of two or more characters.",
                  "disabled": true
                },
                {
                  "key": "min_price",
                  "value": "",
                  "description": "Lowest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the net bid price.",
                  "disabled": true
                },
                {
                  "key": "max_price",
                  "value": "",
                  "description": "Highest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the net bid price.",
                  "disabled": true
                },
                {
                  "key": "depth",
                  "value": "",
                  "description": "How many bids to return per wine, in book order — Cru’s own bids first, so depth=1 is not always the highest price. Omit it for every bid. Default: every level.",
                  "disabled": true
                },
                {
                  "key": "landed_stock_only",
                  "value": "",
                  "description": "true for only bids that require stock that has already landed; false for only bids that do not. Omit it for both. Default: both.",
                  "disabled": true
                },
                {
                  "key": "deliverable_warehouse",
                  "value": "",
                  "description": "Only bids that stock in any of these warehouses could fill: UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA. Case-insensitive. Pass a portfolio line’s warehouse.deliverable_warehouse_code to see the bids it can fill.",
                  "disabled": true
                },
                {
                  "key": "include_market_price",
                  "value": "false",
                  "description": "Add market_price — Cru’s market price for the wine, as a number — to each wine.",
                  "disabled": true
                },
                {
                  "key": "include_last_trade",
                  "value": "false",
                  "description": "Add last_trade — the last traded price and when — to each wine.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `market:read`.\n\nExplore Cru’s live bid book: what buyers will pay for each wine, net of commission, and the stock each bid accepts.\n\n**A bid is an opportunity to sell.** Bid prices are net of Cru’s commission: what a seller receives. Read the requirements on each bid to see which stock can fill it.\n\n**Pagination counts wines, not bids.** limit, offset and total refer to wines. Each wine carries every bid on it unless you set depth.\n\n**Book order puts Cru’s own bids first.** Wines with a Cru bid come first, newest first, then by best bid. Within a wine, Cru’s bids lead, then the rest highest first — so depth=1 is not always the best price."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.markets?.[0]?.bids?.[0]?.code !== undefined) pm.collectionVariables.set('marketBidCode', String(body?.data?.markets?.[0]?.bids?.[0]?.code));",
                  "if (body?.data?.markets?.[0]?.lwin18 !== undefined) pm.collectionVariables.set('lwin18', String(body?.data?.markets?.[0]?.lwin18));"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve a market bid",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/bids/{{marketBidCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "bids",
                "{{marketBidCode}}"
              ]
            },
            "description": "Scope: `market:read`.\n\nRetrieve one live bid by its opaque code, with the wine, net price, quantity and fulfilment requirements in one object.\n\n**Reconfirm before you act.** A missing, expired or malformed bid returns the same BID_NOT_FOUND / 404. Your own bids are returned, with is_own_bid set."
          }
        },
        {
          "name": "List bids on one wine",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/wines/{{lwin18}}/bids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "wines",
                "{{lwin18}}",
                "bids"
              ],
              "query": [
                {
                  "key": "min_price",
                  "value": "",
                  "description": "Lowest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the net bid price.",
                  "disabled": true
                },
                {
                  "key": "max_price",
                  "value": "",
                  "description": "Highest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the net bid price.",
                  "disabled": true
                },
                {
                  "key": "depth",
                  "value": "",
                  "description": "How many bids to return per wine, in book order — Cru’s own bids first, so depth=1 is not always the highest price. Omit it for every bid. Default: every level.",
                  "disabled": true
                },
                {
                  "key": "landed_stock_only",
                  "value": "",
                  "description": "true for only bids that require stock that has already landed; false for only bids that do not. Omit it for both. Default: both.",
                  "disabled": true
                },
                {
                  "key": "deliverable_warehouse",
                  "value": "",
                  "description": "Only bids that stock in any of these warehouses could fill: UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA. Case-insensitive. Pass a portfolio line’s warehouse.deliverable_warehouse_code to see the bids it can fill.",
                  "disabled": true
                },
                {
                  "key": "include_market_price",
                  "value": "false",
                  "description": "Add market_price — Cru’s market price for the wine, as a number — to each wine.",
                  "disabled": true
                },
                {
                  "key": "include_last_trade",
                  "value": "false",
                  "description": "Add last_trade — the last traded price and when — to each wine.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `market:read`.\n\nEvery live bid on one wine, by LWIN18, as a single market: the bid book’s shape and filters, without paging.\n\n**No bids is an empty list, not a 404.** When the wine has no live bids — or your filters remove them all — the answer is 200 with bids: [], and the wine is still described. Only a wine Cru does not know is NOT_FOUND / 404."
          }
        },
        {
          "name": "List market offers",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/offers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "offers"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "100",
                  "description": "Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of wines to skip.",
                  "disabled": true
                },
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated LWIN18 codes. The books do not check the format, so a code that is not an LWIN18 simply matches nothing.",
                  "disabled": true
                },
                {
                  "key": "min_price",
                  "value": "",
                  "description": "Lowest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the gross offer price.",
                  "disabled": true
                },
                {
                  "key": "max_price",
                  "value": "",
                  "description": "Highest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the gross offer price.",
                  "disabled": true
                },
                {
                  "key": "depth",
                  "value": "",
                  "description": "How many offers to return per wine, cheapest first. Omit it for every offer. Default: every level.",
                  "disabled": true
                },
                {
                  "key": "include_market_price",
                  "value": "false",
                  "description": "Add market_price — Cru’s market price for the wine, as a number — to each wine.",
                  "disabled": true
                },
                {
                  "key": "include_last_trade",
                  "value": "false",
                  "description": "Add last_trade — the last traded price and when — to each wine.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `market:read`.\n\nExplore Cru’s offer book: wines for sale on the market you call and their gross asking prices, cheapest first.\n\n**An offer is an opportunity to buy.** Offer prices are gross: what a buyer pays. The book covers the market you call, in its currency.\n\n**Pagination counts wines, not offers.** limit, offset and total refer to wines, ordered by their cheapest offer. Each wine carries its offers, cheapest first.\n\n**Refreshed by Cru’s market index.** The offer book, with each offer’s status and eta, is rebuilt by Cru’s market index rather than on every change, so it can trail the live market. Re-read an offer before acting on it."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.markets?.[0]?.offers?.[0]?.code !== undefined) pm.collectionVariables.set('marketOfferCode', String(body?.data?.markets?.[0]?.offers?.[0]?.code));",
                  "if ((body?.data?.markets || []).flatMap(m => m.offers || []).flatMap(o => o.photo_urls || [])[0] !== undefined) pm.collectionVariables.set('photoId', String((body?.data?.markets || []).flatMap(m => m.offers || []).flatMap(o => o.photo_urls || [])[0]).split(\"/\").pop());"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve a market offer",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/offers/{{marketOfferCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "offers",
                "{{marketOfferCode}}"
              ]
            },
            "description": "Scope: `market:read`.\n\nRetrieve one offer by its opaque code: the wine, its gross price, quantity, stock status, ETA, duty status, condition and warehouse."
          }
        },
        {
          "name": "List offers on one wine",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/wines/{{lwin18}}/offers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "wines",
                "{{lwin18}}",
                "offers"
              ],
              "query": [
                {
                  "key": "min_price",
                  "value": "",
                  "description": "Lowest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the gross offer price.",
                  "disabled": true
                },
                {
                  "key": "max_price",
                  "value": "",
                  "description": "Highest price to include, inclusive, in whole units of the market’s currency — 1200 is 1,200.00. Compared with the gross offer price.",
                  "disabled": true
                },
                {
                  "key": "depth",
                  "value": "",
                  "description": "How many offers to return per wine, cheapest first. Omit it for every offer. Default: every level.",
                  "disabled": true
                },
                {
                  "key": "include_market_price",
                  "value": "false",
                  "description": "Add market_price — Cru’s market price for the wine, as a number — to each wine.",
                  "disabled": true
                },
                {
                  "key": "include_last_trade",
                  "value": "false",
                  "description": "Add last_trade — the last traded price and when — to each wine.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `market:read`.\n\nEvery offer on one wine, by LWIN18, cheapest first, as a single market: the offer book’s shape and filters, without paging.\n\n**No offers is an empty list, not a 404.** When the wine has no offers — or your filters remove them all — the answer is 200 with offers: [], and the wine is still described. Only a wine Cru does not know is NOT_FOUND / 404.\n\n**Refreshed by Cru’s market index.** Offers, with their status and eta, come from the same index as the offer book, so they can trail the live market. Re-read an offer before acting on it."
          }
        },
        {
          "name": "Retrieve a photo",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "X-No-Auth",
                "value": "1",
                "description": "Dropped by the pre-request script: this endpoint takes no credentials."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/photos/{{photoId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "photos",
                "{{photoId}}"
              ]
            },
            "description": "One photo of a wine on offer, as the image. It needs no credentials, so the photo_urls that link here work in an <img> tag.\n\n**Only photos of offers in the book.** Once the offer has left the book, its photo links return NOT_FOUND / 404."
          }
        }
      ]
    },
    {
      "name": "Your bids",
      "item": [
        {
          "name": "List your bids",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/bids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "bids"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "",
                  "description": "Comma-separated, e.g. matched,cancelled, from live, matched, complete, cancelled, expired and error, in any case. To see every bid, list all six: there is no all. Anything else is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated 18-digit LWIN18 codes.",
                  "disabled": true
                },
                {
                  "key": "client_ref",
                  "value": "",
                  "description": "Only bids with this client_ref, in any case. Older bids may share one.",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "description": "Number of bids to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of bids to skip.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `bids:read`.\n\nYour own bids on every Cru site, newest first — the live ones unless you ask for others — priced in your market’s currency, with what matched and its orders.\n\n**Live bids only, unless you ask.** Without status, only live bids come back. Name the ones you want, such as status=matched,complete, or list all six to see every bid."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.bids?.[0]?.code !== undefined) pm.collectionVariables.set('bidCode', String(body?.data?.bids?.[0]?.code));"
                ]
              }
            }
          ]
        },
        {
          "name": "Place a bid",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/bids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "bids"
              ]
            },
            "description": "Scope: `bids:write`.\n\nPlace a bid to buy a wine at your own price per unit. It rests on Cru for 90 days and fills when a seller accepts it.\n\n**To buy at the asking price, use an offer.** This places a resting bid. To buy an offer straight away at its price, POST /market/offers/{code}/buy.\n\n**The bid must fit your bidding allowance.** price × quantity above the account’s allowance is refused with TRADE_REFUSED, and its message gives both amounts. So is an untraded wine, or an account that cannot bid.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"lwin18\": \"{{lwin18}}\",\n  \"quantity\": 1,\n  \"price\": 100.0\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Retrieve one of your bids",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/bids/{{bidCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "bids",
                "{{bidCode}}"
              ]
            },
            "description": "Scope: `bids:read`.\n\nOne of your own bids by its code, with how much has matched, its status and expiry. Bids from other venues are not found here."
          }
        },
        {
          "name": "Change a bid",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/bids/{{bidCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "bids",
                "{{bidCode}}"
              ]
            },
            "description": "Scope: `bids:write`.\n\nChange the price, quantity, local_only or auto_transfer of one of your live Cru bids. Any change, even to an option alone, runs it for 90 days from then.\n\n**What cannot be changed.** A partly matched bid, a bid that is no longer live, and a bid from another venue are refused with TRADE_REFUSED. So is a price above the cheapest offer, even when you change only an option: buy that offer instead.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Cancel a bid",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/bids/{{bidCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "bids",
                "{{bidCode}}"
              ]
            },
            "description": "Scope: `bids:write`.\n\nCancel one of your live Cru bids by its code. A partner credential sends its reference in a JSON body.\n\n**A DELETE with a body.** A partner credential’s cancel must carry {\"reference\": \"…\"} as its JSON body. Check that your HTTP client sends a body on DELETE — not every client does by default.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Renew a bid",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/bids/{{bidCode}}/renew",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "bids",
                "{{bidCode}}",
                "renew"
              ]
            },
            "description": "Scope: `bids:write`.\n\nPut one of your bids back on the market for 90 days at the same price, quantity and currency: an expired or cancelled bid, or a live bid in its last 7 days.\n\n**To change the price as well, change the bid.** Renewing keeps the bid exactly as it was. To reprice a live bid, PATCH /bids/{code} instead: that also runs it for 90 days from the change.\n\n**Which bids can be renewed.** renewable on the bid says whether this endpoint takes it: an expired or cancelled bid, or a live one with 7 days or fewer left, with nothing matched. Others get TRADE_REFUSED — for a partly matched bid, place a new one for the rest. So, even if renewable, does a bid from another venue, an account that cannot bid, or a bid over your allowance on its site.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Your offers",
      "item": [
        {
          "name": "List your offers",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers"
              ],
              "query": [
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated 18-digit LWIN18 codes.",
                  "disabled": true
                },
                {
                  "key": "wine_name",
                  "value": "",
                  "description": "Only wines whose name contains every word given, as GET /wines matches a name, such as “Lafite 2010”: one to six words of two or more characters. Anything else is refused with VALIDATION_INVALID_VALUE.",
                  "disabled": true
                },
                {
                  "key": "current_location_code",
                  "value": "",
                  "description": "Only portfolio lines of wine stored now at any of these, as warehouse.current_location_code gives them, comma-separated, such as UK_DRAK,IB_20,ADDR_123: a Cru warehouse code (UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA), IB_ and the inbond_address_id of an inbond warehouse outside Cru, or ADDR_ ",
                  "disabled": true
                },
                {
                  "key": "deliverable_warehouse_code",
                  "value": "",
                  "description": "Only portfolio lines whose warehouse.deliverable_warehouse_code is any of these Cru warehouses, comma-separated: UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA. An unknown code is refused with VALIDATION_INVALID_VALUE.",
                  "disabled": true
                },
                {
                  "key": "stock_type",
                  "value": "",
                  "description": "Only portfolio lines of these stock types, comma-separated, such as cru,external. A stock_type is cru, external, supplier or bpo, and only a corporate supplier has the last two. Any other value is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "stock_status",
                  "value": "",
                  "description": "Only portfolio lines with any of these stock_status values, comma-separated: in_stock, in_transit or due_in. Case-insensitive. It matches the stock_status each line shows, so a supplier’s own offers and its BPO stock are due_in. Any other value is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "duty_paid",
                  "value": "",
                  "description": "true for only the portfolio lines whose duty is paid; false for only those whose duty is not. Omit it for both. Default: both.",
                  "disabled": true
                },
                {
                  "key": "condition_status",
                  "value": "",
                  "description": "Only portfolio lines with any of these condition_status values, comma-separated: verified, client_reserves or apd. Case-insensitive. A line with no condition_status matches none of them. Any other value is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "description": "Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of wines to skip.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `offers:read`.\n\nYour portfolio’s listed lines, by wine: what buyers pay and what you receive for each.\n\n**Your portfolio, listed lines only.** GET /offers answers as GET /portfolio?is_listed=true does: the same wines, lines and fields, and the same filters but is_listed, with the wines under data.offers rather than data.wines. A wine’s total_quantity is the units listed.\n\n**Filters narrow each wine too.** wine_name, current_location_code, deliverable_warehouse_code, stock_type, stock_status, duty_paid and condition_status combine with each other and with lwin. They choose the portfolio lines shown inside each wine, as well as which wines appear.\n\n**offers:read shows what the wine cost.** GET /offers and GET /offers/{code} need offers:read, not portfolio:read, yet their lines carry everything GET /portfolio’s do, pricing.cost included: a credential that can read your listings sees what the listed wine cost you."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.offers?.[0]?.portfolio?.[0]?.portfolio_id !== undefined) pm.collectionVariables.set('portfolioId', String(body?.data?.offers?.[0]?.portfolio?.[0]?.portfolio_id));"
                ]
              }
            }
          ]
        },
        {
          "name": "Create an offer (cru)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers"
              ]
            },
            "description": "Scope: `offers:write`.\n\nList a line of your portfolio stored with Cru, wine you hold outside Cru, or your own stock as a supplier, for sale at a price per unit you choose.\n\n**Wine stored with Cru or held outside it, or a supplier’s own stock.** stock_type cru puts units of a line of your portfolio stored with Cru on sale. stock_type external lists wine in your own storage, for accounts Cru has set up to sell it. stock_type supplier adds an offer of your own stock, for a supplier whose offer feed Cru imports. To sell into a bid now, POST /market/bids/{code}/sell.\n\n**A line stored with Cru.** Its units go on sale at your price, and you receive it less Cru’s commission: the listed line’s pricing gives commission_percent, commission and net_proceeds. Listing moves them to a listed line with a portfolio_id of its own, not the one you sent, so take the answer’s for PATCH and DELETE /offers/{code}. A line already listed is refused: change its price or quantity with PATCH /offers/{code} instead. Removing the offer later only takes it off sale.\n\n**Your next offer feed import replaces a supplier offer.** An offer listed with stock_type supplier joins your offers on Cru only until your next offer feed import to Cru, which replaces it, as it replaces all your offers: your feed stays the source of truth. To keep selling the wine, put it in your feed too.\n\n**A supplier offer.** It is sold from your own warehouse, so it takes no warehouse_code, and it must be priced in your offer feed’s currency: on a Cru site that quotes in another, it is refused with TRADE_REFUSED, and the message names the currency. Its line comes back with stock_type supplier, and your price as both pricing.listing_price and pricing.net_proceeds. You can change it afterwards with PATCH /offers/{code}, like any of your supplier offers.\n\n**Removing wine held outside Cru takes it out of your portfolio.** Listing wine held outside Cru creates its units in your Cru portfolio, in bond. Removing the offer later deletes them again.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"stock_type\": \"cru\",\n  \"portfolio_id\": \"{{unlistedPortfolioId}}\",\n  \"quantity\": 1,\n  \"price\": 100.0\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Create an offer (external)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers"
              ]
            },
            "description": "Scope: `offers:write`.\n\nList a line of your portfolio stored with Cru, wine you hold outside Cru, or your own stock as a supplier, for sale at a price per unit you choose.\n\n**Wine stored with Cru or held outside it, or a supplier’s own stock.** stock_type cru puts units of a line of your portfolio stored with Cru on sale. stock_type external lists wine in your own storage, for accounts Cru has set up to sell it. stock_type supplier adds an offer of your own stock, for a supplier whose offer feed Cru imports. To sell into a bid now, POST /market/bids/{code}/sell.\n\n**A line stored with Cru.** Its units go on sale at your price, and you receive it less Cru’s commission: the listed line’s pricing gives commission_percent, commission and net_proceeds. Listing moves them to a listed line with a portfolio_id of its own, not the one you sent, so take the answer’s for PATCH and DELETE /offers/{code}. A line already listed is refused: change its price or quantity with PATCH /offers/{code} instead. Removing the offer later only takes it off sale.\n\n**Your next offer feed import replaces a supplier offer.** An offer listed with stock_type supplier joins your offers on Cru only until your next offer feed import to Cru, which replaces it, as it replaces all your offers: your feed stays the source of truth. To keep selling the wine, put it in your feed too.\n\n**A supplier offer.** It is sold from your own warehouse, so it takes no warehouse_code, and it must be priced in your offer feed’s currency: on a Cru site that quotes in another, it is refused with TRADE_REFUSED, and the message names the currency. Its line comes back with stock_type supplier, and your price as both pricing.listing_price and pricing.net_proceeds. You can change it afterwards with PATCH /offers/{code}, like any of your supplier offers.\n\n**Removing wine held outside Cru takes it out of your portfolio.** Listing wine held outside Cru creates its units in your Cru portfolio, in bond. Removing the offer later deletes them again.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"stock_type\": \"external\",\n  \"lwin18\": \"{{lwin18}}\",\n  \"quantity\": 1,\n  \"price\": 100.0,\n  \"warehouse_code\": \"UK_DRAK\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Create an offer (supplier)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers"
              ]
            },
            "description": "Scope: `offers:write`.\n\nList a line of your portfolio stored with Cru, wine you hold outside Cru, or your own stock as a supplier, for sale at a price per unit you choose.\n\n**Wine stored with Cru or held outside it, or a supplier’s own stock.** stock_type cru puts units of a line of your portfolio stored with Cru on sale. stock_type external lists wine in your own storage, for accounts Cru has set up to sell it. stock_type supplier adds an offer of your own stock, for a supplier whose offer feed Cru imports. To sell into a bid now, POST /market/bids/{code}/sell.\n\n**A line stored with Cru.** Its units go on sale at your price, and you receive it less Cru’s commission: the listed line’s pricing gives commission_percent, commission and net_proceeds. Listing moves them to a listed line with a portfolio_id of its own, not the one you sent, so take the answer’s for PATCH and DELETE /offers/{code}. A line already listed is refused: change its price or quantity with PATCH /offers/{code} instead. Removing the offer later only takes it off sale.\n\n**Your next offer feed import replaces a supplier offer.** An offer listed with stock_type supplier joins your offers on Cru only until your next offer feed import to Cru, which replaces it, as it replaces all your offers: your feed stays the source of truth. To keep selling the wine, put it in your feed too.\n\n**A supplier offer.** It is sold from your own warehouse, so it takes no warehouse_code, and it must be priced in your offer feed’s currency: on a Cru site that quotes in another, it is refused with TRADE_REFUSED, and the message names the currency. Its line comes back with stock_type supplier, and your price as both pricing.listing_price and pricing.net_proceeds. You can change it afterwards with PATCH /offers/{code}, like any of your supplier offers.\n\n**Removing wine held outside Cru takes it out of your portfolio.** Listing wine held outside Cru creates its units in your Cru portfolio, in bond. Removing the offer later deletes them again.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"stock_type\": \"supplier\",\n  \"lwin18\": \"{{lwin18}}\",\n  \"quantity\": 1,\n  \"price\": 100.0\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Retrieve one of your offers",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers/{{portfolioId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers",
                "{{portfolioId}}"
              ]
            },
            "description": "Scope: `offers:read`.\n\nOne listed line of your portfolio, by its portfolio_id: its wine as GET /offers gives it, with that line alone.\n\n**One item of GET /offers.** data.offer is what GET /offers gives as one item of data.offers: the same wine and fields, with only the line whose portfolio_id you gave under portfolio, and total_quantity its units. A listing’s code gives the wine with all the listing’s lines.\n\n**offers:read shows what the wine cost.** GET /offers and GET /offers/{code} need offers:read, not portfolio:read, yet their lines carry everything GET /portfolio’s do, pricing.cost included: a credential that can read your listings sees what the listed wine cost you."
          }
        },
        {
          "name": "Change an offer",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers/{{portfolioId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers",
                "{{portfolioId}}"
              ]
            },
            "description": "Scope: `offers:write`.\n\nChange the asking price or quantity of one listed line of your portfolio, or of a whole listing. A repriced line comes back with a new portfolio_id.\n\n**What a change does depends on where the wine is.** Held outside Cru (external): a lower quantity deletes units, a higher one creates them. Stored with Cru: units come off or go on sale, up to what you hold in that warehouse. Supplier offers take a lasting override. BPO stock cannot be changed.\n\n**Change one line, or a whole listing.** Given a listed line’s portfolio_id, only that line’s units change: the preview’s before and after quantities are the line’s, and its code the listing’s. A lower quantity takes units off that line alone. Repriced, the line gets a new portfolio_id, which the offer in the answer carries. Given a listing’s code, every line of the listing changes.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Remove an offer",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/offers/{{portfolioId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "offers",
                "{{portfolioId}}"
              ]
            },
            "description": "Scope: `offers:write`.\n\nTake one listed line of your portfolio, or a whole listing, off sale. Wine stored with Cru stays in your portfolio; wine held outside Cru is removed from it.\n\n**A DELETE with a body.** A partner credential sends {\"reference\": \"…\"} as the JSON body. Supplier offers cannot be removed here — they are switched off on the Cru website — and BPO stock cannot be taken off sale.\n\n**Remove one line, or a whole listing.** Given a listed line’s portfolio_id, only that line’s units come off sale, and the preview’s offer has that line alone. Given a listing’s code, every line of the listing comes off sale.\n\n**Back in your portfolio, under another portfolio_id.** Wine stored with Cru stays in your portfolio, no longer listed, so the answer’s offer has its line under another portfolio_id than the one you sent, with is_listed false. That line can hold more units than came off sale, when you hold others of the same kind that are not listed. Send its portfolio_id to POST /offers with stock_type cru to list them again. Wine held outside Cru is deleted, so offer is null.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Your portfolio",
      "item": [
        {
          "name": "Retrieve your portfolio",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/portfolio",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "portfolio"
              ],
              "query": [
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated 18-digit LWIN18 codes.",
                  "disabled": true
                },
                {
                  "key": "wine_name",
                  "value": "",
                  "description": "Only wines whose name contains every word given, as GET /wines matches a name, such as “Lafite 2010”: one to six words of two or more characters. Anything else is refused with VALIDATION_INVALID_VALUE.",
                  "disabled": true
                },
                {
                  "key": "current_location_code",
                  "value": "",
                  "description": "Only portfolio lines of wine stored now at any of these, as warehouse.current_location_code gives them, comma-separated, such as UK_DRAK,IB_20,ADDR_123: a Cru warehouse code (UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA), IB_ and the inbond_address_id of an inbond warehouse outside Cru, or ADDR_ ",
                  "disabled": true
                },
                {
                  "key": "deliverable_warehouse_code",
                  "value": "",
                  "description": "Only portfolio lines whose warehouse.deliverable_warehouse_code is any of these Cru warehouses, comma-separated: UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA. An unknown code is refused with VALIDATION_INVALID_VALUE.",
                  "disabled": true
                },
                {
                  "key": "stock_type",
                  "value": "",
                  "description": "Only portfolio lines of these stock types, comma-separated, such as cru,external. A stock_type is cru, external, supplier or bpo, and only a corporate supplier has the last two. Any other value is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "stock_status",
                  "value": "",
                  "description": "Only portfolio lines with any of these stock_status values, comma-separated: in_stock, in_transit or due_in. Case-insensitive. It matches the stock_status each line shows, so a supplier’s own offers and its BPO stock are due_in. Any other value is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "duty_paid",
                  "value": "",
                  "description": "true for only the portfolio lines whose duty is paid; false for only those whose duty is not. Omit it for both. Default: both.",
                  "disabled": true
                },
                {
                  "key": "condition_status",
                  "value": "",
                  "description": "Only portfolio lines with any of these condition_status values, comma-separated: verified, client_reserves or apd. Case-insensitive. A line with no condition_status matches none of them. Any other value is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "is_listed",
                  "value": "",
                  "description": "true for only the portfolio lines listed for sale, as GET /offers gives them; false for only those that are not. Omit it for both. Default: both.",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "description": "Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of wines to skip.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `portfolio:read`.\n\nThe wine you hold, by wine: where each unit is, its status, condition and cost, any listing, and each wine’s market price, lowest offer and highest bid.\n\n**Filters narrow each wine too.** wine_name, current_location_code, deliverable_warehouse_code, stock_type, stock_status, duty_paid and condition_status combine with each other and with lwin. They choose the portfolio lines shown inside each wine, as well as which wines appear.\n\n**A corporate supplier’s own stock.** A corporate supplier also sees its own offers, as stock_type supplier, and its stock on broking purchase orders, as stock_type bpo. Both are always due_in, as market offers show them: the stock reaches Cru only once it is sold. Neither has a cost or can be sold into a bid. Cru takes no commission from a supplier, and adds its margin for buyers instead, so both are listed at what the supplier is paid: pricing.listing_price and pricing.net_proceeds are each the supplier’s own price or, for BPO stock, the purchase order’s cost, and commission_percent, commission and settlement_fee are 0.0. Its own offers are in “Your warehouse”, of warehouse.location_type supplier. BPO stock is named after the purchase order’s supplier warehouse, of warehouse.location_type inbond with its IB_ current_location_code, or is in “Your warehouse” when the order names none. Both always have a warehouse.deliverable_warehouse_code: the Cru warehouse they go to once sold, which for stock at the supplier’s own warehouse is the Cru warehouse in its country, as market offers show it."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.wines?.[0]?.portfolio?.[0]?.portfolio_id !== undefined) pm.collectionVariables.set('unlistedPortfolioId', String(body?.data?.wines?.[0]?.portfolio?.[0]?.portfolio_id));"
                ]
              }
            }
          ]
        },
        {
          "name": "List your purchases",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/trades/purchases",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "trades",
                "purchases"
              ],
              "query": [
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated 18-digit LWIN18 codes.",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "",
                  "description": "Only order lines with a unit in any of these states, comma-separated, in any case: in_portfolio, for_sale, sold, in_transit or delivered, as units[].status gives them. A line with no units stored with Cru matches none. Anything else is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "sort",
                  "value": "traded_at",
                  "description": "What to order by: traded_at, the date of the order, the only choice.",
                  "disabled": true
                },
                {
                  "key": "direction",
                  "value": "desc",
                  "description": "desc for newest first, or asc for oldest first.",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "description": "Number of purchases to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of purchases to skip.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `trades:read`.\n\nWhat you have bought on Cru, by order line, newest first, with each order’s status, invoice and units.\n\n**The order and invoice links are for the customer.** order_url and invoice_url are pages on the Cru site the order was placed on, for the customer signed in there: an API key or access token does not open them. Show them to the customer rather than fetching them."
          }
        },
        {
          "name": "List your sales",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/trades/sales",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "trades",
                "sales"
              ],
              "query": [
                {
                  "key": "lwin",
                  "value": "",
                  "description": "Only these wines: up to 20 comma-separated 18-digit LWIN18 codes.",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "",
                  "description": "Only sales in any of these states, comma-separated, in any case: transfer_needed, awaiting_transfer, on_purchase_order or delivered_to_cru. Anything else is refused with VALIDATION_UNSUPPORTED_VALUE.",
                  "disabled": true
                },
                {
                  "key": "deliverable_warehouse_code",
                  "value": "",
                  "description": "Only sales of wine held outside Cru going to any of these Cru warehouses, comma-separated: UK_DRAK, HK_KERRY, SG_TOLL, FR_DARTESS, US_NAPA. Wine stored with Cru matches none. An unknown code is refused with VALIDATION_INVALID_VALUE.",
                  "disabled": true
                },
                {
                  "key": "sort",
                  "value": "traded_at",
                  "description": "What to order by: traded_at, the date of the sale, the only choice.",
                  "disabled": true
                },
                {
                  "key": "direction",
                  "value": "desc",
                  "description": "desc for newest first, or asc for oldest first.",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "description": "Number of sales to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced.",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "description": "Number of sales to skip.",
                  "disabled": true
                }
              ]
            },
            "description": "Scope: `trades:read`.\n\nWhat you have sold on Cru, one unit at a time, newest first: commission, what you received and profit.\n\n**One sale per unit.** Each unit sold is its own sale, with quantity 1, its cru_id and no order number. sold_price, commission and settlement_fee take the sale down to net_proceeds, what you received, and profit_loss sets that against cost.\n\n**Wine held outside Cru, on its way to Cru.** Once it sells, wine held outside Cru goes to the Cru warehouse deliver_to names, by deliver_by. status says how far it has got: transfer_needed until a transfer to Cru is booked, then awaiting_transfer, with transfer_ref naming the transfer; on_purchase_order while it is due in on a purchase order; and delivered_to_cru once it is there. Wine stored with Cru has no deliver_to, and is always delivered_to_cru."
          }
        }
      ]
    },
    {
      "name": "Buy and sell",
      "item": [
        {
          "name": "Buy an offer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/offers/{{marketOfferCode}}/buy",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "offers",
                "{{marketOfferCode}}",
                "buy"
              ]
            },
            "description": "Scope: `orders:write`.\n\nBuy one offer on Cru’s market now, at its asking price, paid from your Cru account credit or on invoice and kept in your Cru storage.\n\n**The offer you name, and bids:write as well.** There is no “buy at the lowest offer”: pick one from GET /market/wines/{lwin18}/offers. The purchase needs bids:write besides orders:write. To sell into a bid instead, POST /market/bids/{code}/sell.\n\n**A partner key should send max_price.** A partner’s purchase has no preview, so max_price is what holds the price you read from the book. If the offer costs more, nothing is bought.\n\n**Paid from credit or on invoice, never by card.** It goes through the Cru website’s own Buy now, paid from your Cru account credit, or on invoice if your account has invoice terms. The wine is kept in your Cru storage. If neither covers the total, nothing is bought, and the message says how much credit is missing.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"quantity\": 1\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Sell into a bid (cru)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/bids/{{marketBidCode}}/sell",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "bids",
                "{{marketBidCode}}",
                "sell"
              ]
            },
            "description": "Scope: `orders:write`.\n\nSell into one bid on Cru’s market now, at its price after commission, credited to your Cru account: a line of your portfolio, or new stock.\n\n**The bid you name, and offers:write as well.** There is no “sell at the best bid”: pick one from GET /market/wines/{lwin18}/bids by its requirements. The sale needs offers:write besides orders:write. To buy an offer instead, POST /market/offers/{code}/buy.\n\n**A partner key should send min_price.** A partner’s sale has no preview, so min_price is what holds the price you read from the book. If the bid pays less, nothing is sold.\n\n**Wine held outside Cru, not in your portfolio yet.** For accounts Cru has set up to sell it, as the website’s Sell Now does: send stock_type external and warehouse_code, with no portfolio_id, and Cru creates the units at that warehouse and fills the bid with them at once — or deletes them again, and sells nothing, if the fill fails. You set no price: you receive the bid’s price less that warehouse’s settlement fee — its settlement_fee in GET /warehouses, such as GBP 6.00 per unit at UK_DRAK — and a corporate account pays none. Selling confirms the wine is free from material faults, in its original packaging, in a professional warehouse and not duty paid, and that you will transfer it to that warehouse; Cru emails you the purchase order. A bid that takes landed stock only cannot be filled this way.\n\n**Your own stock, as a supplier.** A supplier whose offer feed Cru imports can sell stock that is not in its feed: send stock_type supplier, with no portfolio_id. Cru adds an offer of just that quantity to your feed, at the feed’s warehouse, verified and not duty paid, and fills the bid with it at once, so selling it all leaves nothing on sale. If it cannot fill the bid, or the fill fails, it is taken back and nothing is sold. Supplier stock, new or a line of your portfolio, fills only bids placed on Cru.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"stock_type\": \"cru\",\n  \"portfolio_id\": \"{{unlistedPortfolioId}}\",\n  \"quantity\": 1\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Sell into a bid (external)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/bids/{{marketBidCode}}/sell",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "bids",
                "{{marketBidCode}}",
                "sell"
              ]
            },
            "description": "Scope: `orders:write`.\n\nSell into one bid on Cru’s market now, at its price after commission, credited to your Cru account: a line of your portfolio, or new stock.\n\n**The bid you name, and offers:write as well.** There is no “sell at the best bid”: pick one from GET /market/wines/{lwin18}/bids by its requirements. The sale needs offers:write besides orders:write. To buy an offer instead, POST /market/offers/{code}/buy.\n\n**A partner key should send min_price.** A partner’s sale has no preview, so min_price is what holds the price you read from the book. If the bid pays less, nothing is sold.\n\n**Wine held outside Cru, not in your portfolio yet.** For accounts Cru has set up to sell it, as the website’s Sell Now does: send stock_type external and warehouse_code, with no portfolio_id, and Cru creates the units at that warehouse and fills the bid with them at once — or deletes them again, and sells nothing, if the fill fails. You set no price: you receive the bid’s price less that warehouse’s settlement fee — its settlement_fee in GET /warehouses, such as GBP 6.00 per unit at UK_DRAK — and a corporate account pays none. Selling confirms the wine is free from material faults, in its original packaging, in a professional warehouse and not duty paid, and that you will transfer it to that warehouse; Cru emails you the purchase order. A bid that takes landed stock only cannot be filled this way.\n\n**Your own stock, as a supplier.** A supplier whose offer feed Cru imports can sell stock that is not in its feed: send stock_type supplier, with no portfolio_id. Cru adds an offer of just that quantity to your feed, at the feed’s warehouse, verified and not duty paid, and fills the bid with it at once, so selling it all leaves nothing on sale. If it cannot fill the bid, or the fill fails, it is taken back and nothing is sold. Supplier stock, new or a line of your portfolio, fills only bids placed on Cru.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"stock_type\": \"external\",\n  \"quantity\": 1,\n  \"warehouse_code\": \"UK_DRAK\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Sell into a bid (supplier)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/market/bids/{{marketBidCode}}/sell",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "market",
                "bids",
                "{{marketBidCode}}",
                "sell"
              ]
            },
            "description": "Scope: `orders:write`.\n\nSell into one bid on Cru’s market now, at its price after commission, credited to your Cru account: a line of your portfolio, or new stock.\n\n**The bid you name, and offers:write as well.** There is no “sell at the best bid”: pick one from GET /market/wines/{lwin18}/bids by its requirements. The sale needs offers:write besides orders:write. To buy an offer instead, POST /market/offers/{code}/buy.\n\n**A partner key should send min_price.** A partner’s sale has no preview, so min_price is what holds the price you read from the book. If the bid pays less, nothing is sold.\n\n**Wine held outside Cru, not in your portfolio yet.** For accounts Cru has set up to sell it, as the website’s Sell Now does: send stock_type external and warehouse_code, with no portfolio_id, and Cru creates the units at that warehouse and fills the bid with them at once — or deletes them again, and sells nothing, if the fill fails. You set no price: you receive the bid’s price less that warehouse’s settlement fee — its settlement_fee in GET /warehouses, such as GBP 6.00 per unit at UK_DRAK — and a corporate account pays none. Selling confirms the wine is free from material faults, in its original packaging, in a professional warehouse and not duty paid, and that you will transfer it to that warehouse; Cru emails you the purchase order. A bid that takes landed stock only cannot be filled this way.\n\n**Your own stock, as a supplier.** A supplier whose offer feed Cru imports can sell stock that is not in its feed: send stock_type supplier, with no portfolio_id. Cru adds an offer of just that quantity to your feed, at the feed’s warehouse, verified and not duty paid, and fills the bid with it at once, so selling it all leaves nothing on sale. If it cannot fill the bid, or the fill fails, it is taken back and nothing is sold. Supplier stock, new or a line of your portfolio, fills only bids placed on Cru.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"stock_type\": \"supplier\",\n  \"quantity\": 1\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Your addresses",
      "item": [
        {
          "name": "List your inbond addresses",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/addresses/inbond",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "addresses",
                "inbond"
              ]
            },
            "description": "Scope: `addresses:read`.\n\nThe inbond addresses on your account: each an inbond warehouse, with your bond account number, site code and nickname there.\n\n**Only inbond addresses.** Not your other addresses or payment details. A connected app gets addresses:read only by asking for it by name: an app that asks for nothing in particular does not."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const body = pm.response.code < 300 ? pm.response.json() : null;",
                  "if (body?.data?.inbond_addresses?.[0]?.inbond_address_id !== undefined) pm.collectionVariables.set('inbondAddressId', String(body?.data?.inbond_addresses?.[0]?.inbond_address_id));"
                ]
              }
            }
          ]
        },
        {
          "name": "Add an inbond address",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/addresses/inbond",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "addresses",
                "inbond"
              ]
            },
            "description": "Scope: `addresses:write`.\n\nSave an inbond address on your account: an inbond warehouse from GET /warehouses/inbond, and your bond account number there.\n\n**Never your default address.** It is saved as the Cru website’s address form saves one with “In bond” ticked, at the warehouse’s own address, and is never made your default. A warehouse Cru does not list has to be added by Cru first: suggest it with POST /warehouses/inbond if Cru has granted you warehouses:suggest, or the customer emails customerservice@cruworldwine.com.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\",\n  \"inbond_address_id\": {{inbondWarehouseId}},\n  \"account_number\": \"TEST-123\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Remove an inbond address",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/addresses/inbond/{{inbondAddressId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "addresses",
                "inbond",
                "{{inbondAddressId}}"
              ]
            },
            "description": "Scope: `addresses:write`.\n\nRemove an inbond address from your account: the one you added last at an inbond warehouse, by its inbond_address_id from GET /addresses/inbond.\n\n**Never your default address.** Your default billing or delivery address on Cru is not removed: choose another default on the Cru website first. Your other addresses are never changed.\n\n**A DELETE with a body.** A partner credential sends {\"reference\": \"…\"} as the JSON body.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reference\": \"{{$guid}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Confirmations",
      "item": [
        {
          "name": "Retrieve a confirmation",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/confirmations/{{confirmationCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "confirmations",
                "{{confirmationCode}}"
              ]
            },
            "description": "See what a confirmation code stands for and how far it has got: pending, executing, completed, failed, expired or cancelled.\n\n**Connected apps only.** Confirmations belong to the app that staged them. A partner credential never has one, and gets CONFIRMATION_NOT_FOUND."
          }
        },
        {
          "name": "Confirm an instruction",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/confirmations/{{confirmationCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "confirmations",
                "{{confirmationCode}}"
              ]
            },
            "description": "Carry out an instruction a connected app staged. Only the same app, for the same customer and market, can confirm it.\n\n**Only after the customer says yes.** This is the call that trades with the customer’s money or wine. Show them preview.summary and confirm only on their explicit yes."
          }
        },
        {
          "name": "Discard an instruction",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/confirmations/{{confirmationCode}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "confirmations",
                "{{confirmationCode}}"
              ]
            },
            "description": "Withdraw a pending instruction before it is confirmed. It answers 204 with no body, and the code cannot be used again."
          }
        }
      ]
    }
  ],
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// CLIENT-KEY and CLIENT-SECRET for a partner credential, else the connected app's bearer token.",
          "const key = pm.variables.get('clientKey');",
          "if (pm.request.headers.has('X-No-Auth')) {",
          "  pm.request.headers.remove('X-No-Auth');",
          "} else if (key) {",
          "  pm.request.headers.upsert({ key: 'CLIENT-KEY', value: key });",
          "  pm.request.headers.upsert({ key: 'CLIENT-SECRET', value: pm.variables.get('clientSecret') });",
          "} else if (pm.variables.get('accessToken')) {",
          "  pm.request.headers.upsert({ key: 'Authorization', value: 'Bearer ' + pm.variables.get('accessToken') });",
          "}"
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Every answer is the envelope; a staged write's code is kept for Confirmations.",
          "const type = pm.response.headers.get('Content-Type') || '';",
          "if (type.includes('application/json')) {",
          "  const body = pm.response.json();",
          "  pm.test('envelope', () => {",
          "    pm.expect(body).to.have.keys(body.status === 'OK' ? ['status', 'message', 'meta', 'data'] : ['status', 'message', 'meta', 'data', 'errors']);",
          "  });",
          "  if (pm.response.code === 202 && body.data && body.data.confirmation) {",
          "    pm.collectionVariables.set('confirmationCode', body.data.confirmation.code);",
          "  }",
          "}"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "market",
      "value": "uk",
      "description": "Market host: uk, us, hk, sg, eu, ae or cn."
    },
    {
      "key": "baseUrl",
      "value": "https://{{market}}.cruworldwine.com/api/v1",
      "description": "The API root for the market."
    },
    {
      "key": "clientKey",
      "value": "",
      "description": "Partner credential: CLIENT-KEY. Leave empty to use accessToken."
    },
    {
      "key": "clientSecret",
      "value": "",
      "description": "Partner credential: CLIENT-SECRET, shown once when it is issued."
    },
    {
      "key": "accessToken",
      "value": "",
      "description": "Connected app: an OAuth 2.0 access token, used when clientKey is empty."
    },
    {
      "key": "warehouseCode",
      "value": "UK_DRAK"
    },
    {
      "key": "inbondWarehouseId",
      "value": ""
    },
    {
      "key": "lwin18",
      "value": ""
    },
    {
      "key": "marketBidCode",
      "value": ""
    },
    {
      "key": "marketOfferCode",
      "value": ""
    },
    {
      "key": "photoId",
      "value": ""
    },
    {
      "key": "bidCode",
      "value": ""
    },
    {
      "key": "portfolioId",
      "value": "",
      "description": "A listed portfolio line, from List your offers."
    },
    {
      "key": "unlistedPortfolioId",
      "value": "",
      "description": "A portfolio line to list or sell, from List your portfolio."
    },
    {
      "key": "inbondAddressId",
      "value": ""
    },
    {
      "key": "confirmationCode",
      "value": "",
      "description": "Saved by any staged (202) write."
    }
  ]
}
