Permission scopes
Every credential and every connected app carries a fixed set of scopes. An endpoint the scopes do not cover is refused with AUTH_INSUFFICIENT_SCOPE / 403, and details.required_scope names what was missing. Over MCP, a tool they do not cover is refused with JSON-RPC error -32600 and HTTP 403, its message naming the scope.
| SCOPE | ALLOWS | CONNECTED APPS |
|---|---|---|
meta:read | Check the connection, and read Cru’s warehouses and the inbond warehouses REST: GET /ping, GET /warehouses and /warehouses/{code}, GET /warehouses/inbond and /warehouses/inbond/{id} MCP: whoami, list_warehouses, list_inbond_warehouses | Required: cannot be unticked |
market:read | Read Cru’s bid and offer books, and the bids and offers on each wine REST: /market, /market/bids and /market/bids/{code}, /market/offers and /market/offers/{code}, /market/wines/{lwin18} and its /bids and /offers MCP: search_wines, list_bids, list_offers, list_market | Offered, ticked |
wines:read | Look up wine reference data REST: GET /wines, GET /wines/{lwin18} MCP: get_wine | Offered, ticked |
portfolio:read | Read your portfolio REST: GET /portfolio MCP: get_my_portfolio | Offered, ticked |
bids:read | Read your own bids REST: GET /bids, GET /bids/{code} MCP: list_my_bids | Offered, ticked |
offers:read | Read your own listings, with what the listed wine cost REST: GET /offers, GET /offers/{code} MCP: list_my_listings | Offered, ticked |
trades:read | Read what you have bought and sold, with the order and invoice references REST: GET /trades/purchases, GET /trades/sales MCP: list_my_purchases, list_my_sales | Offered, ticked |
addresses:read | Read your own inbond addresses REST: GET /addresses/inbond MCP: list_inbond_addresses | Offered, ticked, only when asked for by name |
bids:write | Place, change, renew and cancel bids REST: POST /bids, PATCH /bids/{code}, DELETE /bids/{code}, POST /bids/{code}/renew; POST /market/offers/{code}/buy with orders:write MCP: place_bid, update_bid, cancel_bid, renew_bid, confirm_instruction; buy_wine with orders:write | Offered, unticked |
offers:write | List, change and remove offers REST: POST /offers, PATCH /offers/{code}, DELETE /offers/{code}; POST /market/bids/{code}/sell with orders:write MCP: list_for_sale, update_listing, remove_offers, confirm_instruction; sell_to_bid with orders:write | Offered, unticked |
orders:write | Buy and sell straight away, alongside bids:write or offers:write REST: POST /market/offers/{code}/buy (with bids:write), POST /market/bids/{code}/sell (with offers:write) MCP: buy_wine (with bids:write), sell_to_bid (with offers:write) | Offered, unticked |
addresses:write | Save and remove inbond addresses REST: POST /addresses/inbond, DELETE /addresses/inbond/{id} MCP: add_inbond_address, remove_inbond_address, confirm_instruction | Offered, unticked |
warehouses:suggest | Suggest inbond warehouses Cru does not list REST: POST /warehouses/inbond MCP: suggest_inbond_warehouse | Never: partner credentials only |
webhooks:manageReserved | Manage webhook subscriptions REST: Reserved: webhooks are not built MCP: — | Never: partner credentials only |
A write scope does not include its read
Scopes are matched exactly. bids:write can place a bid but cannot list your bids — that is bids:read. Ask for both when you need both.
orders:write never works alone
orders:write is “buy and sell straight away”: it is needed withbids:write to buy an offer, and withoffers:write to sell into a bid. Buying is POST /market/offers/{code}/buy or the MCP tool buy_wine; selling is POST /market/bids/{code}/sell or sell_to_bid.
Partner credentials
Cru grants a partner credential the scopes your integration needs, from any in the table. GET /ping lists what yours holds. To change them, contact Cru.
warehouses:suggest is granted only this way. A suggestion adds to the list of inbond warehouses every customer picks from, so Cru grants it on request, and never to a connected app. Without it, a customer whose warehouse is not listed emails [email protected] and Cru adds it.
Connected apps
An app asks for scopes when it sends the customer to sign in, and the customer decides. On Cru’s consent page meta:read cannot be unticked; the read scopes start ticked; the trading scopes and addresses:write start unticked, even when the app asked for them, so a customer opts in to each. An app that asks for nothing gets the read scopes but addresses:read, which it must ask for by name. warehouses:suggest and webhooks:manage are never offered to an app: one that asks for either has it dropped. How consent works →
webhooks:manage is in the catalogue and can be granted, but there is no webhook endpoint yet: calling one returns NOT_FOUND / 404.