Create an offer
List 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.
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.
How this write runs
offer.list| Partner credentialCLIENT-KEY · CLIENT-SECRET | Executes at once and answers 201. The body must carry a reference: send the identical request again after a timeout and Cru replays the first outcome instead of acting twice. |
| Connected appAuthorization: Bearer | Answers 202 with a confirmation code and does nothing else. It runs only when the app calls POST /confirmations/{code} within 15 minutes, after the customer agrees. |
Writes & confirmations, in full →
Request body
APPLICATION/JSON| FIELD | DESCRIPTION |
|---|---|
| referencestring · 1–50 chars · partners: required | Your idempotency key: letters and digits, then . _ : or - allowed. Required on a partner credential’s write and kept for good, so a retry with it can never act twice. Ignored for connected apps. |
| stock_typestring · required | What you are listing: cru, a line of your portfolio stored with Cru; external, wine you hold outside Cru; or supplier, your own stock as a supplier whose offer feed Cru imports. The fields below that say which of them they are for are refused for the others, with VALIDATION_UNKNOWN_PARAMETER. Anything else, bpo included, is refused with VALIDATION_INVALID_VALUE: BPO stock cannot be listed through the API. |
| portfolio_idstring · cru only · required | The line to list, from GET /portfolio: one with stock_type cru that is not listed yet (is_listed false). Its units go on sale as a listed line with a portfolio_id of its own, which the answer gives. |
| lwin18string · 18 digits · external or supplier only · required | The wine. Cru must trade it. |
| quantityinteger · 1–1000 · required | Units to list. For cru, at most the line’s quantity. |
| pricenumber · > 0 · required | Price per unit in the market’s currency, to at most 2 decimal places. For cru and external, the asking price, what the buyer pays: the line’s pricing.listing_price. For supplier, what you receive: buyers pay Cru’s price, and the line gives yours as both pricing.listing_price and pricing.net_proceeds. |
| warehouse_codestring · external only · required | The Cru warehouse it is sold through: one GET /warehouses marks sells_your_inbond_wine for you. The line gives it back as warehouse.deliverable_warehouse_code. |
| condition_statusstring · external or supplier only · optional | verified (Verified), client_reserves (Client Reserve) or apd (As per description). For external, it defaults to, and cannot exceed, the level Cru set for your account. For supplier, it defaults to verified, or to apd when duty_paid is true, which takes nothing else. |
| condition_textstring · ≤ 200 chars · supplier only · optional | What buyers are told about the condition. Required for apd, and refused for verified; client_reserves may have it. Duty-paid stock says “Duty Paid in the UK” unless you give it. |
| duty_paidboolean · supplier only · optional | true when the duty has been paid, which makes the offer apd. Defaults to false, in bond. |
| costnumber · > 0 · external only · optional | What you paid per unit, for your records. |
| inbond_address_idinteger · ≥ 1 · external only · optional | The inbond warehouse the wine is in now, from GET /warehouses/inbond. Leave it out if you are not sure where the wine is: Cru records it as not sure, as the website’s “Not Sure” option does. |
Any other field is refused with VALIDATION_UNKNOWN_PARAMETER / 400.
Every POST /offers now needs stock_type. Send external to list wine you hold outside Cru, as before: a request without stock_type is refused with VALIDATION_REQUIRED_FIELD / 422. A connected app’s preview gives stock_type back, straight after summary.
Only wine held outside Cru could be listed here; wine stored with Cru was listed only on the Cru website. Now send stock_type cru, the portfolio_id of a line that is not listed yet, quantity and price, and nothing else: lwin18 and the other fields are for external and supplier only. stock_type supplier adds an offer of a supplier’s own stock.
The offer a write answers with is no longer a listing: it is now the wine as GET /offers/{code} gives it, with only the lines the units written are on now. Each line has its portfolio_id, stock_type, pricing and warehouse in place of the listing’s code, held, price, proceeds and holding_ids. A write’s answer no longer carries a listing’s code — only a connected app’s PATCH preview names the listing it changes — so give a line’s portfolio_id to PATCH or DELETE /offers/{code} to change or remove its units.
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.
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.
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.
Listing wine held outside Cru creates its units in your Cru portfolio, in bond. Removing the offer later deletes them again.
Response fields
201 Created · 202 AcceptedA partner credential gets 201 and the wine, with the line just listed. A connected app gets 202 and a confirmation.
Executed 201
actionstring
The action that ran, such as bid.place.
statusstring
completed.
offerobject | null
The wine as GET /offers/{code} gives it, with only the lines of what was just listed. Their portfolio_id is what PATCH and DELETE /offers/{code} take: for cru, a new one, not the one you sent.
Staged 202
confirmation.codestring
cnf_ and 43 more characters. A secret: the only handle on the instruction, valid for 15 minutes, once.
confirmation.actionstring
The action staged, such as bid.place.
confirmation.statusstring
pending.
confirmation.expires_atdatetime
RFC 3339 UTC.
confirmation.previewobject
summary, stock_type, then for cru portfolio_id, then lwin18, wine_name, quantity, price, total and currency; then for external warehouse_code, condition_status, cost and inbond_address_id — null when not given — or for supplier duty_paid, condition_status and condition_text, as they will be listed.
Errors
A request without stock_type, quantity or price, cru without portfolio_id, external or supplier without lwin18, or external without warehouse_code, returns VALIDATION_REQUIRED_FIELD / 422, and an lwin18 that is not 18 digits VALIDATION_INVALID_VALUE / 422. A wine Cru does not trade is TRADE_REFUSED / 422, “Cru does not trade wine … so it cannot be listed.” For cru, a portfolio_id that is not a line of your portfolio, or a line of another stock_type, returns VALIDATION_INVALID_VALUE / 422; a line already listed, one that needs a condition check first, more units than it can list, or units sold or moved before you confirm, TRADE_REFUSED / 422. For external, a warehouse not set up for your account, a condition_status above your level or an inbond_address_id GET /warehouses/inbond does not list returns VALIDATION_INVALID_VALUE / 422, and an account not set up to sell wine held outside Cru TRADE_REFUSED / 422. For supplier, apd without condition_text returns VALIDATION_REQUIRED_FIELD / 422; condition_text with verified, or duty_paid true with a condition_status other than apd, VALIDATION_INVALID_VALUE / 422; and an account with no supplier offers on Cru, or a price in a currency other than your feed’s, TRADE_REFUSED / 422. Missing or invalid credentials return AUTH_INVALID_CREDENTIALS / 401. A credential without offers:write gets AUTH_INSUFFICIENT_SCOPE / 403. View all error codes →