You are viewing a non-production environment — the API surface may differ from production.

Creating inventory items

Inventory item types, prices, VAT, tags, visibility and existing-reference relationships.

Use POST /api/v1/inventory to create an item and PUT /api/v1/inventory/{id} to update it. Send camelCase property names, an X-API-Key with inventory.create or inventory.update, and the location you are acting for in X-Location-Id. The REST reference lists every property you can write and every property an item is returned with, each with a description. A returned property is writable only if the write schema lists it; any other key in a write request is ignored, not stored and not reported as an error.

A minimal item

This request creates a regular 51.00 SEK item with 12% VAT and nothing else. Replace the location ID with an accessible location:

{
  "locationId": 123,
  "title": "Example coffee",
  "itemType": "regular",
  "pricings": [{ "name": "BASE", "price": 51, "order": 0 }],
  "vatValue": 12
}

No tags, category, modifier groups or visibility are needed for an item to have a price and VAT.

Item type

itemType is a catalogue classification string of at most 50 characters. It is not a closed enum: any string is stored unchanged, including "". Only recognised values carry behaviour:

ValueEffect
regularAn ordinary, separately sold product. Use this unless another value applies. null and "" behave the same.
variantA sub-product that exists only as an option of another product (a modifier choice). It is left out of delivery-marketplace menus and can be hidden from POS search.
deliveryA shipping-fee product, selectable as the fee for storefront deliveries.
gift_cardEach sale issues a gift card for the line amount. Where an integration provides the location's gift cards, the sale loads the integration's card instead.

Any other string is stored and returned but changes nothing. Creating an item requires the property; it may be empty.

Three similarly named fields have different contracts:

FieldContract
Inventory itemType / items.item_typeCatalogue string, described above.
Legacy item_meta_data.item_type_keyReference to the legacy item-type dictionary; not written by the inventory itemType input.
BigQuery purchase_line_items.item_typeRecorded sales-line classification; see the goods export rules. Not interchangeable with catalogue type.

Price

Set the price with pricings or an existing pricingGroupId, then read the item back to check calculatedPrice. basePrice is accepted on create for older clients but ignored.

pricings is a list of rules applied in order, each starting from the result of the one before. price is in currency units: 51 means 51.00 SEK in an SEK location.

nameEffectmetadata
BASESets the price to price. Use one BASE rule for a plain price.none
FIXEDSets the price to price, or adds price to it with mode: "relative".mode: absolute (default) or relative
PERCENTChanges the price by percentage percent.percentage, and optionally maxAdjustment, minPrice, maxPrice in minor units
FORMULASets the price to the result of formula.formula, and optionally variables

Any other name is stored but does not change the price. scheduleId limits a rule to a schedule and channelTypes to channels (for example ["POS"]); with neither, the rule always applies. On update, pricings replaces the item's rules; send a rule's id back to keep its ID.

A pricingGroupId links an existing shared price instead of the item's own rules; it is unrelated to variantGroupIds, which link modifier/option groups.

VAT

Set VAT with vatId (an ID from GET /api/v1/vat-rates) or vatValue. If both are sent, vatId wins.

vatValue has different units on write and read:

DirectionUnit12% is sent/returned as
Write (POST, PUT)percentage, 0–10012
Read (GET)basis points1200

So never send back the vatValue you read; use the returned vatId instead. Writes reject values above 100.

VAT is not required to save a price. When a create request has no vatId, vatValue or accountIds, the item gets the location country's default VAT, which is often wrong for the product (for example food versus alcohol), so set it explicitly. takeawayVatId is a separate rate used when the line is sold as takeaway.

Tags

Send tags as an object keyed by tag type:

{ "CATEGORY_PRIMARY": ["DRINK"], "ALLERGEN": ["NUTS"], "CUSTOM": ["oat-milk"] }
  • Tags are references, not upserts. Tag types and tag keys must already exist. Unknown ones are skipped silently: the request still succeeds and nothing is created. List category tags with GET /api/v1/category-tags; create a custom tag first with POST /api/v1/custom-tags. Read the item back to confirm which tags were attached.
  • CUSTOM resolves existing custom tags in the CUISINE custom-tag category.
  • tags replaces. When an update includes tags, every non-custom tag type you leave out is removed, CATEGORY_PRIMARY included. To change allergens without losing the category, send both. Omit CUSTOM to keep custom tags; CUSTOM: [] clears them.
  • No tag is required for price or VAT. CATEGORY_PRIMARY groups the item in reports and analytics.
  • The legacy string-array shape (["DRINK"]) passes validation but matches no tag type, so it removes every non-custom tag. Use the object shape.

Visibility

visibility (POS, KIOSK, TAKEAWAY, ONLINE, GENERAL) is a legacy field. It is stored but nothing reads it: it does not change where the item is sold, and it is not returned when you read the item. To control where an item can be ordered, use:

  • channel availability in the menu layouts (returned on the item as channelAvailability),
  • POST /api/v1/inventory/{itemId}/availability with ACTIVATE or DEACTIVATE to put the item on or take it off sale everywhere,
  • allowedTabTypes to limit the kinds of tab it can be ordered onto.

isAvailable on the item reports the result. Sending isAvailable in a create or update request has no effect.

Existing references

variantGroupIds, printerGroupIds, accountIds, servingCenterId, pricingGroupId, vatId and takeawayVatId all reference existing resources; none of them creates one. Create or look up the referenced resource first. On update, a supplied array replaces the item's links and [] removes them.

vatValue is the one exception: it finds the VAT rate with that value, creating it if needed.

Free-form objects

Every write property is listed in the reference, and any other key is ignored. Two properties are deliberately free-form, and the reference shows them as such:

  • metadata is yours. Karma stores it as you send it, returns it unchanged and reads none of its keys. Put your own identifiers here, prefixed with your company or system name; keys are case-sensitive, and keep article numbers as strings to preserve leading zeros. Never store secrets.
  • context holds settings for particular kinds of item. Its public key is gift_card, the settings of a gift_card item (amounts, card types, fees). Karma's own systems keep other keys in it, so treat it as read-modify-write: an update replaces the whole object.

Updates

An update changes only the properties it includes. Relationship arrays, pricings, tags, context and metadata replace what is stored. To merge selected top-level metadata keys instead, use PATCH /api/v1/inventory/{id}/metadata.

Reading items

GET /api/v1/inventory (list) and GET /api/v1/inventory/{id} (single item) return the same item, with a few properties only on one of them; the reference marks those "List endpoint only" or "Single-item GET only". posIntegration appears only when the location has a POS integration. Money is in currency units, except properties ending in Cents, which are minor units (öre). The exception is ministockCents: stock in hundredths of a unit, not money.

On this page