Share a product with a category
Partner key + restaurant key. Shows a product the restaurant already has also in this category, without copying it. A shared product is one product shown in several categories, often in different menus (for example the dinner pizzas in the lunch menu). Price, sizes, allergens, addons, sold out (isAvailable) and isActive live on the one product, so a change applies in every menu it is in. It can be ordered while any of its categories is in a menu that is in service. GET /api/v1/menu lists it in each category with shared: true where it does not live, and GET …/menus/{menuId} has sharedFrom. Use it instead of creating the same dish twice. Placed last in the category. Only to a category in another menu than the one the product lives in. Idempotent: sharing it again gives 200 with created: false. At most 2000 shared products (placements) per restaurant. GET /api/v1/menu is CDN-cached (s-maxage=30, stale-while-revalidate=300, at most 330 seconds), so the website can show the old menu for up to six minutes; the response has notice about it.
Authentication
The partner key (lbp_test_… or lbp_live_…), sent as Authorization: Bearer lbp_… and created in LettBestilt Partner under Partner key. It belongs to the whole partner, not to a restaurant, and only works against /api/v1/partner. Server to server only: a request with an Origin header is rejected with 403 FORBIDDEN, and the key must never be in a browser. A TEST key sees and creates only sandboxes; LIVE keys work once LettBestilt Partner is open. A suspended or archived partner, a revoked key and a restaurant key (lbs_…) here give 401 UNAUTHORIZED; an expired key gives 401 KEY_EXPIRED.
The restaurant’s own key (lbs_test_… or lbs_live_…) for calls about one restaurant in the partner API, sent together with the partner key. The key must have full access (scope *, otherwise 403 INSUFFICIENT_SCOPE), belong to a restaurant the partner owns and be in the same environment as the partner key. A restaurant that does not exist, belongs to another partner or does not match the key always gives the same 404 RESTAURANT_NOT_FOUND. Older keys without an environment in the prefix (lbs_<random>) are not accepted here; rotate them in LettBestilt Partner.
Path parameters
The restaurant’s slug. It must match the restaurant key in X-LettBestilt-Restaurant-Key.
Request
The product’s id from GET …/menus/{menuId}. It lives in another category, often in another menu.

