Beta

The Partner Trading API v1 is in beta — endpoints and response shapes may still change.

Developers
Cru World Wine
API v1 · REST & MCP
Your offers

List your offers

Your portfolio’s listed lines, by wine: the asking price and what you receive for each.

GET/offersLIVE
Required scopeoffers:readAuthentication requiredTry it
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.

Query parameters

ALL OPTIONAL
PARAMETERDESCRIPTION
lwinstring · CSV · ≤ 20 Only these wines: up to 20 comma-separated 18-digit LWIN18 codes. Anything else is refused with VALIDATION_INVALID_VALUE.
wine_namestring · ≤ 100 chars 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; one-letter words are left out. Anything else is refused with VALIDATION_INVALID_VALUE.
current_location_codestring · CSV · ≤ 50 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_ and the id of your own address. Case-insensitive. Unlike deliverable_warehouse_code, it says where the wine is, not where it is delivered from. An ADDR_ code that is not one of your addresses matches nothing. Anything else is refused with VALIDATION_INVALID_VALUE.
deliverable_warehouse_codestring · CSV 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.
stock_typestring · CSV 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.
stock_statusstring · CSV 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.
duty_paidboolean true for only the portfolio lines whose duty is paid; false for only those whose duty is not. Omit it for both. Default: both
condition_statusstring · CSV 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.
limitinteger · 1–250 Number of wines to return. A larger value is refused with VALIDATION_INVALID_VALUE, not reduced. Default: 50
offsetinteger · ≥ 0 Number of wines to skip. Default: 0
Changed: your listed portfolio lines

data.offers is no longer one flat list of listings: each item is now a wine, as GET /portfolio gives it, with only its listed lines, under portfolio, and pagination counts wines. A line is not a listing and has no code: give its portfolio_id to GET, PATCH or DELETE /offers/{code} instead. A listing whose units differ, such as in cost or condition, shows as several lines. A corporate supplier’s BPO stock on sale is listed now too, as stock_type bpo.

Changed: what each line says

On each line, held is now stock_type, with external for elsewhere. price and currency are now pricing.listing_price, in the wine’s currency, the market’s: a listing priced in another currency is converted at today’s rate. proceeds is now pricing.net_proceeds, with commission_percent, commission and settlement_fee between the two, and holding_ids, an id per unit, is now one portfolio_id for the line. Lines and wines also carry all else GET /portfolio gives them, from stock_status to pricing.cost and market_price.

Changed: warehouse is an object

The warehouse name and warehouse_code are now warehouse.current_location and warehouse.deliverable_warehouse_code, beside two new keys, warehouse.current_location_code and warehouse.location_type. Your own wine held outside Cru has a deliverable_warehouse_code, the Cru warehouse it goes to once sold, only while it is listed.

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.

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.

Response fields

200 OK · paged

data.offers, wines in order of their product name, which wine_name may word differently, as GET /portfolio gives them with only their listed lines: each with its currency — the market’s, which every amount is in — and its lines under portfolio. meta.pagination counts wines.

Each item in offers[]

lwin18string

The 18-digit LWIN: wine, vintage and pack together. Match on all 18 digits.

wine_namestring | null

Cru’s name for the wine.

vintageinteger | null

The vintage year. 1000 means non-vintage.

pack_sizestring | null

Pack format, for example 6x75cl.

product_urlstring | null

The wine’s page on the Cru storefront for the market you called.

currencystring

ISO 4217 currency of every price here: the currency of the market you called. A price bought or listed in another currency is converted at today’s rate.

total_quantityinteger

Units in this wine’s portfolio lines, in total: all you hold of it, or what a filter leaves. On GET /offers, the units listed; on GET /offers/{code} and in what an offer write answers with, the units of the lines shown.

market_pricenumber | null

Cru’s market price for this wine, in its currency. Null when Cru has no price.

lowest_offer_pricenumber | null

The lowest price in Cru’s offer book for this wine, what a buyer would pay now, in its currency. Your own listings count. Null when there is no offer.

highest_bid_pricenumber | null

The highest bid on Cru for this wine, at the net price GET /market/bids quotes — what a seller receives for filling it — in its currency. Your own bids count, and so do bids your stock cannot fill: each bid’s requirements decide that. Null when there is no bid.

portfolioarray<object>

Lines of identical units, described below.

Each item in portfolio[]

portfolio_idstring

Opaque id of the line: PORTFOLIO- and 64 more characters. It is the same on every read and in every currency, and changes when the line does — when its units are listed, repriced or taken off sale, or their stock_status, condition_status or warehouse changes — but not when only its quantity does. A listed line is always inside one listing. GET, PATCH and DELETE /offers/{code} take a listed line’s id, to read, change or remove just its units.

stock_typestring

How the units are held, and so how they sell: cru (stored with Cru), external (in your own storage, sold through Cru), supplier (a corporate supplier’s own offer) or bpo (a supplier’s stock on a broking purchase order). Only a corporate supplier has the last two. Not warehouse.location_type, which says what kind of place they are in.

stock_statusstring

in_stock, in_transit or due_in. A supplier’s own offers and its BPO stock are always due_in: they reach Cru only once sold.

duty_paidboolean

Whether duty has been paid.

condition_statusstring | null

The units’ condition status: verified (Verified), client_reserves (Client Reserve) or apd (As per description).

condition_textstring | null

The written description of the units’ condition. Null when there is none.

is_listedboolean

Whether the units are listed for sale. Always true on GET /offers and GET /offers/{code}, and for a supplier’s own stock.

pricingobject

What the units cost, what they are listed at, what Cru takes and what you receive when they sell, per unit, below. Every amount is in the wine’s currency, converted at today’s rate where the wine was bought or listed in another currency, as Cru’s portfolio page converts them.

pricing.costnumber | null

What you paid per unit. Null when no cost was recorded, as for wine listed without one, for a supplier’s own stock, and when it cannot be converted.

pricing.listing_pricenumber | null

The asking price per unit while the units are listed; otherwise null. For a supplier’s own stock and BPO stock, the same as pricing.net_proceeds: Cru takes no commission from a supplier, and adds its margin for buyers instead.

pricing.commission_percentnumber | null

Cru’s commission, as a percent of pricing.listing_price: 5.0 is 5%. 0.0 for a supplier’s own stock and BPO stock, as Cru takes no commission from a supplier. Null while the line is not listed.

pricing.commissionnumber | null

Cru’s commission per unit: pricing.listing_price less pricing.commission and pricing.settlement_fee is pricing.net_proceeds, to the cent. 0.0 for a supplier’s own stock and BPO stock. Null while the line is not listed.

pricing.settlement_feenumber | null

For wine held outside Cru, the settlement fee per unit of the Cru warehouse it is sold through; 0.0 for every other stock_type. Null while the line is not listed.

pricing.net_proceedsnumber | null

What you receive per unit when the line sells, pricing.listing_price less pricing.commission and pricing.settlement_fee. Null while it is not listed. Units listed at one price can carry different commissions, so a line gives the lowest, with that unit’s commission_percent, commission and settlement_fee. For a supplier’s own offers, the supplier’s own price; for BPO stock, the purchase order’s cost.

photo_urlsarray<string>

Photos of the units in this line, on Cru’s media. [] when there are none.

quantityinteger

Units in this line.

warehouseobject

Where the wine is: its location_type, current_location, current_location_code and deliverable_warehouse_code, below.

warehouse.location_typestring | null

What kind of place it is: cru (a Cru warehouse), inbond (an inbond warehouse outside Cru), address (your own address) or supplier (a supplier’s own stock). Null when you told Cru you do not know where the wine is. Not to be confused with the line’s stock_type.

warehouse.current_locationstring | null

The name of where the wine is now, as the Cru website shows it: a warehouse's name; for wine at your own address, its street lines, which can run over several lines; “Your warehouse” for a supplier's own stock; or “Don't Know” when you told Cru you do not know where it is.

warehouse.current_location_codestring | null

Where the wine is now, as a code to give the current_location_code filter. For wine stored with Cru, the Cru warehouse’s code from GET /warehouses, the same as its deliverable_warehouse_code. For wine in an inbond warehouse outside Cru, IB_ and that warehouse’s inbond_address_id, such as IB_20: the writes and GET /warehouses/inbond/{id} take the number alone. Every inbond warehouse has one, even one GET /warehouses/inbond does not list and so may not find by its id. For wine at your own address, ADDR_ and the address’s id, such as ADDR_123: no endpoint lists address ids, so this is where to find them. Null for a supplier’s own stock, wine whose current_location is “Don't Know”, and wine stored with Cru in a warehouse with no Cru code.

warehouse.deliverable_warehouse_codestring | null

The Cru warehouse the wine can be delivered from, the code bids list as deliverable_warehouses: the one it is in or, for wine held outside Cru, the one it goes to once sold. Your own wine outside Cru has one only while it is listed. A supplier’s own stock and BPO stock have one wherever Cru has a warehouse to deliver to, which for stock at the supplier’s own warehouse is the Cru warehouse in its country, and null in a country with none. Null for wine stored with Cru in a warehouse with no Cru code, which cannot fill a bid. Given to GET /market/bids as deliverable_warehouse, it finds the bids the wine can fill.

Errors

An lwin that is not 18-digit LWIN18 codes, or more than 20 of them, returns VALIDATION_INVALID_VALUE / 422. A wine_name that is not one to six words of two or more characters, or is over 100 characters; a current_location_code that is not a Cru warehouse code, IB_ and an inbond warehouse’s id, or ADDR_ and a whole number from 1, or more than 50 of them; or a deliverable_warehouse_code that is not a Cru warehouse code returns VALIDATION_INVALID_VALUE / 422. A stock_type other than cru, external, supplier or bpo, a stock_status other than in_stock, in_transit or due_in, a duty_paid other than true or false, or a condition_status other than verified, client_reserves or apd returns VALIDATION_UNSUPPORTED_VALUE / 422. is_listed returns VALIDATION_UNKNOWN_PARAMETER / 400: every line here is listed. Missing or invalid credentials return AUTH_INVALID_CREDENTIALS / 401. A credential without offers:read gets AUTH_INSUFFICIENT_SCOPE / 403. View all error codes →

UP NEXT Retrieve one of your offers

API credentials

Enter the client key and secret issued by Cru. They are kept for this browser tab’s session — a reload keeps them, closing the tab or clearing them ends them.

Credentials are never included in copied examples, and are redacted from anything the console prints back.

Request API access

Tell us who you are and what you want to build. Cru issues a client key and secret for your organisation, scoped to what you need.

Markets you trade in (choose one or more)

We use what you send here to reply about API access, and for nothing else. Cloudflare Turnstile checks the form for bots (privacy policy).