Tab Commerce

Call a discount API from Shopify theme JavaScript, no API key needed

Tab Promo's Storefront promotion API is called from your theme's browser JavaScript through your store's Shopify App Proxy, so there is no API key, no secret in theme code and no server or middleware for you to host. Shopify signs every proxied request, Tab Promo rejects any request without a valid signature, and it works out the shop and the logged-in customer itself. The browser only receives display facts, which can include the campaign title and checkout label the merchant already shows at checkout; the price is decided by Shopify checkout.

Plan: Pro — $99/month

See it work

Follow one request. No key anywhere.

theme/assets/promo.js

const facts = await promo.resolve({
  surface: 'cart',
})
// no API key, no token, no server

Through your store’s domain

POST solene.com/apps/tab-promo/promos

  • shopsolene.myshopify.comadded by Shopify
  • logged_in_customer_id7310added by Shopify
  • timestamp1790851200added by Shopify
  • signature3f9a…c41eadded by Shopify

200 · signature verified

progress $28.00 to 10% off

Shop and customer come from Shopify, not from your code.

Follow one request

Response

What your code sends, and what Shopify adds.

Your theme posts the cart to a path on your own domain. Shopify forwards it through the App Proxy and appends the shop, the logged-in customer and a signature. Your code never holds a key.

// Your theme (browser)
POST /apps/tab-promo/promos
{
  "v": 1,
  "context": { "surface": "cart" },
  "cart": { "currency": "USD", "total_price": 7200, "item_count": 2, "items": [ ... ] }
}

// Shopify App Proxy appends, then forwards
?shop=solene.myshopify.com&logged_in_customer_id=7310&timestamp=...&signature=...

// Tab Promo verifies the signature and answers
{ "v": 1, "promos": [ { "primitive": "progress", "current": 7200, "target": 10000, ...,
  "display": { "message": "10% off orders over $100" } } ] }

Examples

Offers you can set up today.

Logged-in VIP offer

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

Your code sends no customer ID. A logged-in VIP gets the free-shipping facts; a guest or untagged customer does not.

A request that skips Shopify

A script calls Tab Promo's server directly instead of going through the store's /apps/ path

It has no Shopify signature, so it is refused with 401 invalid_signature and gets no promotion data.

A tampered gift claim

Browser code marks a $40 scarf as a free gift without the cart qualifying

Shopify checkout re-checks eligibility, variant and quantity, finds the claim invalid, and the scarf stays $40.

A misconfigured client

init({ proxyBase: "https://example.com/api" })

The SDK refuses to start with invalid_proxy_base. Only a relative /apps/... path on your own store domain is accepted.

Setup

How to set it up.

  1. Publish a campaign. Create the campaign in Tab Promo, set its rule to Active, then open Publish and click Publish now.
  2. Find your App Proxy path. Use your store's Tab Promo App Proxy path. It is usually /apps/tab-promo, but it can be changed, so confirm it rather than hard-coding a guess.
  3. Create the client with that path only. Install @tabcommerceio/promo-sdk and call init with proxyBase. Leave out keys, tokens, the shop domain and customer IDs; Tab Promo reads the shop and customer from the signed request, not from your code.
  4. Read facts and run shopper actions. Call resolve or mount to read offers. For gift claims, top-up items and discount codes, use the SDK's helpers, which go through Shopify's own cart endpoints after a shopper clicks.
  5. Test on a development theme. Check a guest and a logged-in customer, then place a real test checkout to confirm the discount Shopify applies.

Good to know

Where it stops.

  • Only works through the App Proxy on your store's own Online Store domain. It is not for Hydrogen, other headless storefronts, or calls from your own server.
  • Read-only for offers. It cannot create campaigns, change discounts or read Admin data.
  • Customer-based offers need a logged-in customer. Guests are evaluated as guests.
  • If Price visibility on the Storefront page is set to Logged-in customers or B2B customers only, other visitors get an empty list of offers.
  • The plan is checked on every request. On Free and Starter the API refuses with subscription_required.

Plan: Pro — $99/month. Compare plans

FAQ

Common questions.

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

No. Shopify's App Proxy signs every request made through your store's /apps/ path, and that signature is what Tab Promo checks. Nothing secret lives in theme code, and there is no backend for you to run.

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

Yes. Install the SDK in your theme build and create a client with your relative App Proxy path. The SDK handles the request format, cart data and timeouts.

How does it know who the customer is?

Shopify adds the logged-in customer to the signed proxy request. Tab Promo reads tags, order count and spend on its side, so your theme never sends customer data.

Is it safe to expose in the browser?

There is nothing secret to expose. The API only describes offers, and any campaign text it returns is the published wording checkout already shows shoppers, never internal notes or unpublished edits. Unsigned requests are refused, and every discount is calculated inside Shopify checkout, which re-checks the cart.

Can I call it from my own server or a Hydrogen app?

No. Requests must arrive through Shopify's App Proxy on the Online Store domain, and the SDK only accepts a relative /apps/... path.

More with Tab Promo

Related guides.