Skip to main content

Catalog Management

Manual Catalog Resync

Once your merchants have connected a location to Stream, we will begin maintaining a mapped record of all items between your POS and the merchants connected DSPs.

Upon onboarding or from a user requested resync from the UI, Stream will fetch the catalog using Get Catalog.

Catalog Objects

Item Family - Top level of all items. I.E. Whopper Combo Item - The main selection options presented for the item family. I.E. Size Modifier Group - Non-primary selections for item family. I.E Toppings, Drink. Modifier - Non-primary selection options for modifier groups. I.E. Cheese/Pickle,Coke/Dr Pepper.

To begin to understand Catalog Objects, start with reading about provider_id and it's purpose. Catalog Object Provider ID

In addition to the core catalog objects (Item Family, Item, Modifier Group, and Modifier), Stream also supports an optional Menu object within the catalog. This can be particularly useful for POSs that have managed menus or even for those that don't support multiple menus but want to provide additional structure to their catalog.

The Menu object can serve several purposes:

  1. Category Ordering: It allows you to specify the order in which categories should be displayed.
  2. Menu Scheduling: You can associate specific hours with a menu, indicating when certain categories are available.

Images

Item Family images must follow the following guidelines for successful propegation to third party platforms.

  • File size < 25MB
  • JPG, WEBP or PNG format
  • 320px ≤ Width ≤ 6000px
  • 320px ≤ Height ≤ 6000px
note

Stream will not reprocess images unless the image URL changes. If you need to update an existing image, ensure you provide a new URL to trigger reprocessing.

Automatic Catalog Resync

With the items existing in multiple places this can become a hassle to manage, which is why we have an automated process to keep everything in sync when changes are made inside the POS.

To take advantage of this functionality, you must configure a process to notify Stream when updates occur.

Send Notification

Send a request to the Catalog Update Notification (POS -> Stream via Webhook) endpoint with the respective provider_id from the Get Locations endpoint.

Notification Behavior

Upon notification of an update, Stream will resync the catalog using Get Catalog and publish changes to connected DSP platforms automatically.

Upon onboarding or from a user-requested resync from the UI, Stream will first re-fetch location data using Get Locations, then fetch the full catalog using Get Catalog. This ensures that location properties such as prep_time_minutes are always kept in sync alongside catalog changes.

Stock Updates

To efficiently manage items and modifiers going out-of-stock at a certain location, we also provide a system to Notify stream when these specific events occur. Implementing this can be advantageous in that a full resync will not need to be done just to sync an update to one object.

Send Notification

Send a request to the Catalog Object Update Notification (POS -> Stream via Webhook) endpoint with the respective location and object provider ids, the type of the object being updated, and the new is_active status of the object. The update will be applied in real-time to the catalog and no resync will be necessary.

Example item family out-of-stock payload

{
"type": "location.catalog.object.updated",
"object": {
"location_id": "test_location",
"object_id": "cheeseburger_provider_id",
"object_type": "item_family",
"object_update": {
"is_active": false
}
}
}

Stream Event Notifications

Your integration can optionally subscribe to scoped events. Currently, the v1/events endpoint supports two events that notify a third-party platform about a menu’s publish status. You may subscribe to:

Menu Publish Success Events – Triggered when a menu is successfully published. Menu Publish Failure Events – Triggered when a menu fails to publish. These events include details on why the publish attempt was rejected or failed.

Please reach out to Stream Support to enable this feature.

Catalog Taxes

Stream has delivered a customizable item-level tax rate solution, which deprecates our catalog wide tax rate implementation.

To set these tax rates through the API you can return the tax array on Get Catalog. Once a tax rate is defined there, you will assign them to items using the item family tax_ids property and the tax rate's provider_id. In the example below, the catalog would have a 9.5% tax rate applied to all items. With one item containing alcohol tax of 6.5%.

{
"category": [...],
"item_family": [{
...,
"name": "Margarita",
"tax_ids":["alcohol_tax"]
},
{
...,
"name": "Cold Food",
"is_tax_exempt": true
}],
"item": [...],
"modifier_group": [...],
"modifier":[...],
"menu": [...],
"tax": [
{
"provider_id": "sales_tax",
"rate": 9.5,
"name": "Sales Tax",
"is_default": true,
},
{
"provider_id": "alcohol_tax",
"rate": 6.5,
"name": "Alcohol Tax"
}
]
}

Alcoholic Items

Stream enables tagging items as alcoholic, to comply with regulations and properly prompt age verifications throughout the order flow.

To set this tax rate through the API you can return the is_alcohol property on item families within the Get Catalog Response. In the example below, the item family would be tagged as alcohol on the platforms it's published too.

{
"provider_id": "booze_provider_id",
"name": "Booze",
"description": "Bottle of Booze",
"is_alcohol": true,
...
}

Allergens

Allergens are a new field that allows you to specify the allergens associated with an item. This field is an array of strings, each representing an allergen.

We will accept allergens based on our defined enum list, refer to the API Spec for the full list of supported allergens.

{
"provider_id": "shrimp_pad_thai",
"name": "Shrimp Pad Thai",
"description": "Classic rice noodles stir-fried with shrimp, eggs, bean sprouts, and peanuts in our house tamarind sauce",
"allergens": ["shellfish", "eggs", "peanuts", "soy"],
...
}

Holidays

Holidays are a new field that allows you to specify the holidays that are applicable to a business. This field is an array of objects, each representing a holiday.

We will accept holidays based on our defined specification, refer to the API Spec for the full list of supported holidays.

{
"holidays": [
{
"date": "12-25",
"recurring_yearly": true,
"name": "Christmas Day",
"hours": [],
}
{
"date": "12-24",
"recurring_yearly": true,
"name": "Christmas Eve",
"hours": ["12:00-18:00"],
}
]
}

Dietary Tags

Dietary tags allow you to specify dietary attributes for item families, such as vegan, vegetarian, gluten-free, etc. This field is an array of strings from our defined enum.

Supported values: vegan, vegetarian, halal, paleo, keto, gluten_free, dairy_free

{
"provider_id": "falafel_wrap_id",
"name": "Falafel Wrap",
"dietary_tags": ["vegan", "gluten_free"],
...
}

Prep Time Overrides

Item families can define prep time overrides that take precedence over the location-level prep_time_minutes. This is useful for items that take significantly longer to prepare.

  • prep_time_exception_minutes — Base prep time for the item (minutes)
  • prep_time_scaling_type — How to scale prep time when quantity > 1: flat (same time regardless of quantity) or percentage (add a percentage per additional item)
  • prep_time_scaling_value — The scaling value used with the scaling type
{
"provider_id": "slow_roast_id",
"name": "Slow Roast Brisket",
"prep_time_exception_minutes": 45,
"prep_time_scaling_type": "percentage",
"prep_time_scaling_value": 10,
...
}

EU Regulatory Fields

For merchants operating in the EU, Stream supports additional regulatory fields on catalog objects.

Additives (Item Family)

The additives field declares EU food additive information. Refer to the API Spec for the full list of supported additive values.

Storage Type (Item Family)

The storage_type field indicates the storage requirement for pre-packaged items. Supported values: frozen, cool_dry.

Country of Origin (Item Family)

The country_of_origin field accepts an ISO 3166-1 alpha-2 country code indicating where the product originated.

Item-Level Regulatory Fields

Items support additional fields for EU pre-packaged item regulations:

  • ingredients — Array of ingredient strings
  • additional_nutritional_details — Key-value map of nutritional information (e.g., { "Carbohydrates": { "value": 10, "unit": "g" } })
  • alcohol_percentage — Alcohol content as a percentage
  • caffeine_content_mg — Caffeine content in milligrams

Item Descriptions and Images

Items support description. images remain supported on item families, modifier groups, and modifiers; item records themselves do not include an images field.

Physical Dimensions and Packaging

Items can include physical dimension and packaging information:

  • dimensions — Length, width, and height with unit values
  • weight — Weight with unit value
  • volume — Volume with unit value
  • count_per_pack — Number of items in a pack (e.g., 6-pack)
  • size_per_pack_item — Dimensions, weight, and volume for individual pack items

Refer to the API Spec for the full type definitions.

Multilingual Catalog (Translations)

Stream supports returning catalog and menu objects in multiple languages. Translations are optional — if your POS only operates in one language no changes are required, and the name / description fields you return today will continue to work unchanged.

default_language on the catalog response

Add a top-level default_language field to your Get Catalog response. It is a BCP 47 language tag (e.g. en-US, de-DE, es-ES) and identifies the language of the canonical name and description fields on every object in the response.

If default_language is omitted, Stream treats the canonical text as untagged and will not forward a default locale to DSPs that require one for multilingual publishing.

name_translations and description_translations on objects

Each catalog object — categories, item families, items, modifier groups, modifiers, and menus — accepts optional name_translations and description_translations arrays. Each entry is { "locale": "<BCP 47 tag>", "value": "<translated text>" }.

Rules:

  • The canonical name / description are always required and represent the default-language text.
  • Do not include the default language inside the translation arrays — Stream filters duplicates during ingest.
  • Locale comparisons are case-insensitive; en-US and en-us are treated as the same locale.
  • Stream falls back to the canonical name / description when a requested locale has no translation.

Example

{
"default_language": "en-US",
"category": [
{
"provider_id": "starters_provider_id",
"name": "Starters",
"name_translations": [
{ "locale": "es-ES", "value": "Entrantes" },
{ "locale": "de-DE", "value": "Vorspeisen" }
],
"item_family_ids": ["platter_provider_id"]
}
],
"item_family": [
{
"provider_id": "platter_provider_id",
"name": "Appetizer Platter",
"name_translations": [
{ "locale": "es-ES", "value": "Plato de Entrantes" },
{ "locale": "de-DE", "value": "Vorspeisenplatte" }
],
"description": "A selection of our most popular starters",
"description_translations": [
{ "locale": "es-ES", "value": "Una selección de nuestros entrantes más populares" }
]
}
]
}

Overrides

Global catalog location_overrides and menu_overrides also accept name_translations and description_translations, so a location- or menu-specific name override can carry its own translation set.

Publishing behavior

  • Stream always publishes the canonical name / description to connected DSPs.
  • DSPs that support multilingual menus also receive the catalog's default_language along with the additional translations.
  • DSPs that don't support multilingual menus receive only the canonical fields.

Global Catalog

If your integration will be using a global catalog, in which only one catalog is created and it is shared across all locations under a given merchant, there are additional features avaiable to make differences across locations easier to manage. Refer to the Global Catalog documentation for further information.