Skip to main content
Version: v1

External IDs

Every entity VoiceBot ingests is keyed by a stable external_id — the one identifier that ties a synced catalog row to your live storefront. Your producer (Laravel / Node / Python) emits it, and the bot passes it back to your host bridge when it acts (add_to_cart, select_variant, …). Producer and bridge must agree on its shape, so it is a contract, not a free-form string.

Grammar

{producer}:{kind}:{id}[:{locale}]
  • producer — the source namespace. The Laravel package uses laravel; other producers use their own (wc, a custom prefix). It keeps ids from different producers from colliding inside one tenant.
  • kind — the entity kind: product, category, variation, page, …
  • id — the raw primary key from your store. The Laravel package wraps your external_id column automatically (laravel:product:84); with a custom EntitySource you build it yourself.
  • locale (optional suffix) — present only on a per-locale row in a multilingual catalog (laravel:product:84:ru).
laravel:product:84 # a product (base / canonical)
laravel:product:84:ru # that product's Russian locale row
laravel:category:12 # a category
laravel:variation:84-red-42 # a product variation

Base vs. translated rows

In a multilingual catalog one product becomes several ingested rows — a base (canonical) row plus one per extra locale. Each locale row carries:

  • its own external_id (often locale-suffixed, e.g. laravel:product:84:ru), and
  • a translation_of pointing at the base row's external_id (laravel:product:84).

You set these with the lang and translation_of config keys — see Mapping → Translations — or emit them from a custom source.

Host-side canonicalization

Hosts key their cart and catalog by the canonical base id, never a per-locale one. So when the bot acts from a non-default locale, the backend canonicalizes product_external_id / variation_external_id back to the base (resolved through translation_of) before it dispatches the action to your bridge.

That means your host bridge always receives the canonical base idlaravel:product:84, never laravel:product:84:ru. Index your products and variants by the base id; you never strip a locale suffix yourself. The step is a no-op for single-language stores, where translation_of is null.

Authoring a custom bridge

Decode and match on the base form. If you mint a new producer prefix, use it consistently on both sides — the bot returns exactly what your producer emitted, after canonicalization.