Skip to navigation

Add a product to a category

Partner key + restaurant key. A new product with sizes and allergens (codes from the catalogue), placed last in the category: name, description, basePrice (needed without sizes, otherwise the default size’s price), up to 8 variants (at most one isDefault), allergens, isVegan, isVegetarian, isPopular, allowedFulfillment, isActive and isAvailable. Prices in øre. Combo menus, images from the image library and upsell are created in the restaurant dashboard. At most 800 active and 2000 products in all (also inactive) per restaurant. A price above 0 and below 500 øre (5 kr) is saved, but gives a warning in warnings ([{ path, message }]): it looks like kroner (149 for 149 kr). Names and descriptions are trimmed and cleaned (links, email addresses, HTML, javascript: and invisible direction marks are removed); the count is in textCleaned, and a name that ends up empty gives 422. 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

AuthorizationBearer

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.

X-LettBestilt-Restaurant-Keystring

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

slugstringRequired

The restaurant’s slug. It must match the restaurant key in X-LettBestilt-Restaurant-Key.

categoryIdstringRequired

The category’s id.

Request

This endpoint expects an object.
namestringRequired1-200 characters
descriptionstring or nullOptional<=1000 characters
basePriceintegerOptional0-10000000

In øre. Required without variants; with sizes it defaults to the default size’s price.

variantslist of objectsOptional

The sizes, at most 8, in order (unique names, case-insensitive). Replaced as a set when changing. Send the ids from GET to keep the rows: a row with id is updated in place, a row without id is new (new id), and rows that are left out are deleted. New ids can make orders fail for up to six minutes, because the website shows the cached menu.

allergenslist of enumsOptional

Allergen codes from the catalogue (as in the menu proposal). Replaced as a set when changing.

isVeganbooleanOptional
isVegetarianbooleanOptional
isPopularbooleanOptional
allowedFulfillmentenumOptional

PICKUP = pickup only, DELIVERY = delivery only, null = both. Enforced by POST /api/v1/orders (422 FULFILLMENT_NOT_ALLOWED).

Allowed values:
isActivebooleanOptional

false = hidden from the menu. Default true.

isAvailablebooleanOptional

false = sold out (shown, but cannot be ordered). Default true.

Response

The product is created.
dataobject

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
404
Not Found Error
409
Conflict Error
422
Unprocessable Entity Error
429
Too Many Requests Error