Tab Commerce

Bring your own storefront UI: a Shopify discount API your theme calls directly

Tab Promo has a Storefront promotion API and a JavaScript SDK (@tabcommerceio/promo-sdk) that your theme's own browser code calls directly, with no API key, no secret and no backend server for you to host. Requests go through your store's Shopify App Proxy, which signs each one, and Tab Promo works out the shop and the logged-in customer on its side. Your theme receives plain promotion facts, such as progress toward a threshold, a tier ladder or eligibility, and renders them in its own design, while Shopify checkout still decides every discount. Where checkout already shows them, facts can also carry the merchant's own campaign title and checkout label, so the theme doesn't have to invent offer copy.

Plan: Pro — $99/month (Free and Starter include the ready-made theme app embeds, not the API)

See it work

Same facts, your design.

theme/assets/promo.js

import { init } from
  '@tabcommerceio/promo-sdk'

const promo = init({
  proxyBase: '/apps/tab-promo',
})

promo.mount({
  request: { surface: 'cart' },
  render({ promos }) {
    // progress, ladder, status
    promos.forEach(drawBrandUi)
  },
})

SOLÈNE

Almost there. $28 from 10% off your bag.

Checkout decides the priceShopify calculates every discount — the UI only shows the offer.

Response

Facts in, your UI out.

A tier offer comes back as a ladder: every rung with its threshold, reward and the tier name you set in Tab Promo, plus where the cart sits now. Amounts are in minor units. Because every tier is named, checkout shows the tier names, so the ladder carries no separate display message. Your theme renders it however it likes; checkout still applies the discount.

{
  "campaign_id": "0192f0a3-d3a1-7000-8000-000000000001",
  "primitive": "ladder",
  "unit": "quantity",
  "current": 7,
  "current_rung": 0,
  "next_rung": 1,
  "remaining_to_next": 3,
  "rungs": [
    {
      "name": "Buy 5",
      "threshold": 5,
      "reward": { "kind": "product_fixed", "amount": 500 },
      "achieved": true
    },
    {
      "name": "Buy 10",
      "threshold": 10,
      "reward": { "kind": "product_fixed", "amount": 1200 },
      "achieved": false
    }
  ]
}

Examples

Offers you can set up today.

Branded spend bar in the cart drawer

Cart subtotal at least $100 → 10% off the order

With $72 in the cart, the API returns a progress fact: $72 of $100, $28 remaining, 72%. Your drawer shows "$28 from 10% off" in your own type.

Tier table on the product page

Product quantity tiers: 2+ → 10% off, 3+ → 15%, 4+ → 20% (counted per variant)

With 2 of the selected variant in the cart, the ladder fact marks the 10% tier as reached and 1 more item to reach 15%. Your theme draws the table.

Gift claim button in your own markup

Cart subtotal at least $50 → free tote bag

Your button calls claimGift. The SDK only resolves once Shopify returns a cart containing the gift, and checkout re-checks the claim before making it $0.

VIP offer without passing customer data

Customer tag is "VIP" and Cart subtotal at least $75 → Free shipping

Your code sends no customer ID. Shopify passes the logged-in customer with the signed request, so tagged VIPs get the offer and guests do not.

Setup

How to set it up.

  1. Build and publish the campaign. In Campaigns, click New campaign, add your rule and set it to Active. Open Publish and click Publish now. The API only describes campaigns that are live.
  2. See the facts before writing code. On the Storefront page, click Open sandbox to see what a sample product, collection, cart or site-wide request returns. View API docs on the same page links to the full contract.
  3. Add the SDK to your theme build. Install @tabcommerceio/promo-sdk@^1.1.0, the stable release on npm, in your theme build.
  4. Create one client with your App Proxy path. Call init with proxyBase set to your store's relative /apps/... path (usually /apps/tab-promo). Do not pass a key, shop domain or customer ID; there is nothing secret to configure.
  5. Render the facts, then test a real checkout. Use resolve or mount for the cart, product, collection or global surface, and draw progress, ladder and status facts in your own markup. Finish on a development theme with a real cart and checkout.

Good to know

Where it stops.

  • Works on Shopify Online Store themes, through the App Proxy on your store's own domain. It is not built for Hydrogen or other storefronts hosted on a different domain.
  • It returns facts, not HTML or components. Your team owns the markup, copy, accessibility and translations.
  • It never sets a price. Shopify checkout applies the discount, and a progress fact that is not yet reached is not a promise that a discount will apply.
  • Reads fail soft: on a timeout, network error or plan denial the SDK returns nothing, so your theme should show no offer rather than block the cart.
  • There is no Admin API client in the SDK. Campaigns are created and published in the Tab Promo admin, not from theme code.

Plan: Pro — $99/month (Free and Starter include the ready-made theme app embeds, not the API). Compare plans

FAQ

Common questions.

Does the API return HTML or ready-made widgets?

No. It returns promotion facts as JSON (progress, ladder and status, with rewards, gifts and top-up products), and the SDK renders nothing. Your theme owns the markup, copy, accessibility, localization and styling. Tier rungs carry the tier names you set in Tab Promo.

Can my theme show the campaign's own title and message?

Yes, when Shopify checkout already shows them. A fact can carry a display object: title is the campaign name, present only when checkout uses it as the label of an automatic-discount rule that has no label of its own, and message is the rule's own checkout discount label. Each is left out when blank, when the message would repeat the title, or when checkout never shows it, such as a tier ladder whose tiers all have names. Both are plain text from the published campaign, exactly as written; your theme inserts them as text and handles translations.

Do I need an API key or a server to use Tab Promo's storefront API?

No. Your theme calls it from the browser through your store's Shopify App Proxy. Shopify signs each request, Tab Promo rejects any request without a valid signature, and the shop and logged-in customer are read from that signed request. There is no key to store and no middleware to host.

Can I call Tab Promo from my theme's JavaScript?

Yes. That is what the SDK is for. Create a client with your relative /apps/... App Proxy path, then call resolve or mount from any script in your theme.

Does Tab Promo work with a custom theme?

Yes, two ways. On every plan, the Tab Promo theme app embeds and product-page block show offers, with text and display settings in the theme editor. From Pro, your developer can build fully custom offer UI with the Storefront SDK.

Can I use the API on the Starter plan?

No. Promotion facts need Pro or Growth; on Free and Starter the request is refused and the SDK returns nothing. Free and Starter stores use the ready-made theme app embeds, and the endpoint that lists top-up product choices works on every plan with live promotions.

Does it work with Hydrogen or a headless storefront?

Not today. The API is reached through Shopify's App Proxy on the store's own Online Store domain, and the SDK reads and updates the cart with Shopify's Online Store cart endpoints.

Can a shopper fake a discount by calling the API?

No. The API only describes offers. The discount is calculated inside Shopify checkout, which checks the cart again, including any free gift claim, before applying anything.

More with Tab Promo

Related guides.