Overview
Layers supports Shopify B2B catalogs end-to-end. When a storefront request includes anidentity.companyLocationId, Layers resolves the catalog assigned to that company location and automatically:
- Restricts search, browse, and block results to the products in that catalog.
- Returns prices and compare-at prices from the catalog’s price list (falling back to market pricing, then variant pricing).
- Hides collections that are excluded from the catalog — requests for those collections return a
404.
companyLocationId is in context, Layers hides B2B-only products, variants, and inventory locations from retail traffic. Retail (DTC) requests never see B2B-only data, and B2B requests never see products outside their assigned catalog.
When to use this
Use B2B catalogs if your store sells to companies through Shopify B2B and you need:- Different product assortments per company or company location.
- Custom price lists per buyer, including currency and compare-at overrides.
- Collection-level access control (some collections visible to retail, some only to specific B2B buyers).
- A single Layers integration that serves both your DTC storefront and your B2B storefront.
How it works
Sync
Layers syncs the following objects from Shopify on install, on each catalog resync, and through real-time webhooks:- Catalogs — title, status, and the assigned price list.
- Catalog products — the set of products and variants each catalog grants access to.
- Catalog price list — per-variant price and compare-at price overrides, including currency.
- Catalog collections — which collections are included or excluded from the catalog.
- Companies and company locations — including which catalogs are assigned to each location.
companies/* and company_locations/* Shopify webhook topics.
Required Shopify access scopes
B2B sync requires the following scopes in addition to the standard Layers scopes:read_customersread_publicationsread_price_lists
Visibility at query time
On every storefront request, Layers checks foridentity.companyLocationId:
- Company location in context — Layers looks up the catalog assigned to that location. Only products assigned to that catalog appear in results, only collections included in that catalog can be browsed, and pricing is sourced from the catalog’s price list.
- No company location in context — B2B-only products, variants, and inventory locations are filtered out, so retail traffic only sees DTC-eligible inventory.
companyLocationId that does not exist, is not synced yet, or has no catalog assigned, the request fails closed — no products are returned. This prevents accidental leaks of retail inventory through unknown IDs.
Buyer authorization
The storefront API is authenticated by anX-Storefront-Access-Token that identifies the store, not the shopper. To stop an anonymous visitor from spoofing another company’s companyLocationId and receiving its wholesale catalog and pricing, Layers verifies buyer membership with Shopify before resolving the catalog.
On every request that includes identity.companyLocationId, Layers:
- Reads
identity.customerIdfrom the request. If it is missing or empty, the request fails with a403. - Calls Shopify’s Admin GraphQL API to confirm that the customer is a contact of the company that owns the requested location.
- Caches the verdict for a short window so subsequent requests from the same buyer skip the round trip. Membership changes made in Shopify propagate through the standard
companies/*andcompany_locations/*webhooks.
customerId, customer not a member of the company, unknown customer, or a Shopify error — returns a 403 with the standard storefront error envelope:
companyLocationId are unaffected and never trigger the membership check.
Pricing precedence
When a catalog is in context, Layers resolves each variant’sprice and compare_at_price in this order:
- Catalog price list — the override defined for the variant in the catalog’s price list, if present.
- Market pricing — the contextual price for the request’s market, if markets sync is enabled and a market is in context.
- Variant pricing — the default Shopify variant price.
Using identity.companyLocationId
Pass the Shopify B2B company location GID for the authenticated buyer on every storefront request, along with the buyer’s customerId.
string
required
Shopify customer ID for the signed-in buyer — either a numeric ID (
8123456789) or a GID (gid://shopify/Customer/8123456789). Required whenever companyLocationId is present so Layers can verify that the customer belongs to the company that owns the location.string
Shopify B2B company location GID — for example,
gid://shopify/CompanyLocation/123456789. Omit this field for retail traffic. When present, Layers looks up the catalog assigned to the company location and uses it to scope products, pricing, and collections.identity.customerId — it only uses customerId to authorize the location you pass.
Request example
FAQs
Q: What happens if I send acompanyLocationId that Layers hasn’t synced yet? A: The request returns zero results. Layers fails closed on unknown company locations so retail inventory is never exposed through an unrecognized ID. Q: Why am I getting a
403 on B2B requests that used to work? A: Storefront requests that include
identity.companyLocationId must now also include the buyer’s identity.customerId, and the customer must belong to the company that owns the location. Requests without a customerId, or with a customerId that Shopify does not recognize as a contact of the location’s company, return 403. Make sure your storefront is passing the signed-in customer’s ID whenever it passes a companyLocationId.
Q: Does this work with markets and localized pricing? A: Yes. Catalog pricing takes precedence, then market pricing, then the default variant price. Mixing B2B and markets is fully supported. Q: Do I need to change anything for DTC traffic?
A: No. Retail requests that omit
companyLocationId continue to work exactly as before, with B2B-only products and inventory locations filtered out automatically.
Q: Are autocomplete suggestions catalog-aware? A: Not yet. Search, browse, blocks, and similar-products endpoints honor
identity.companyLocationId. Catalog-aware autocomplete is on the roadmap.
Q: Where do company and location records come from? A: Layers syncs Shopify B2B companies, their locations, and the catalogs assigned to each location. You only need to pass
companyLocationId at request time — the underlying company, location, and catalog metadata is maintained automatically.
For help wiring identity.companyLocationId into your storefront, contact support.