When building a custom Shopify feature, how do you decide whether to use the Storefront API, Admin API, or Shopify’s AJAX APIs? Is there a simple rule you follow based on what the feature needs to do?
The rule I use isn’t about what the feature does, it’s about where the code runs and what happens if someone reads the token.
Admin API is server side only. It carries an access token that can read orders and customers, so it never goes near a browser. Anything writing products, inventory, orders, metafields or discounts lives here. Worth knowing REST Admin went legacy on 1 Oct 2024, and since 1 Apr 2025 all new public apps have to be built on GraphQL Admin only, so if you’re starting fresh there’s no decision left there.
Ajax API is theme JS on a Shopify hosted storefront. No token at all, because it acts on the current session’s cart through the shop’s own cookies. That’s also its hard boundary, the docs say plainly it can’t be used on a custom storefront. Add to cart, cart drawer, live totals, predictive search, section rendering, all of that is Ajax and reaching for anything heavier is extra work for nothing.
Storefront API is for when you’re rendering the store yourself. Public token, safe in a browser, but it manages its own cart object that is separate from the theme’s session cart. That one catches people out. Build a widget on a normal Liquid theme using the Storefront API and you end up with two carts, then items appear to vanish at checkout.
So the short version. Does it touch data a shopper shouldn’t see, Admin. Is it running inside a Shopify hosted theme, Ajax. Are you rendering the storefront yourself, Storefront.
The messy case is a theme feature that needs admin data, like surfacing something the theme can’t reach. That isn’t an API choice at all. It’s an app proxy or a theme app extension, where the proxy hits your server and your server is the only thing holding the admin token.
What’s the feature? The answer shifts a lot depending on whether it writes anything or just reads.
First, it is necessary to clarify your specific needs, so that they can be combined with the capabilities of different APIs.