Kartlo.App
FeaturesPricingDocsContact
Sign inStart free
  • Getting started
    • Create your store
    • Your desk
    • The Kartlo phone app
    • Stores and organizations
    • Plans and billing
    • AI credits
    • Team and permissions
    • Getting help
  • Products
    • Add products
    • Variants
    • Media library
    • Import products
    • Collections
    • Inventory
    • Stock counts
    • Transfers
    • Purchase orders
    • Gift cards
    • Product labels
    • Product reviews
  • Orders
    • Order lifecycle
    • Draft orders
    • Order payments
    • Fulfilment
    • Returns and refunds
    • Abandoned carts
  • Customers
    • Customers and shopper accounts
    • Segments
    • Companies
    • Subscribers and customer emails
    • Loyalty points
  • Discounts
  • Online store
    • Themes
    • Design Studio
    • Pages
    • Navigation menu
    • Store address and custom domains
    • Publish and password-protect your storefront
    • SEO and sharing
  • Payments
    • Stripe card payments
    • Cash on delivery and manual methods
    • Hosted payment gateways
    • Tabby instalments
    • Finance and payouts
  • Shipping and delivery
  • Markets and languages
  • Arabic and English
  • Taxes
  • Analytics and Live View
    • Analytics
    • Live View
    • Scheduled email reports
  • Settings
  • Security
  • Developers
    • API and webhooks
    • Headless Storefront API
  • Kartlo Apps
    • Remove or cancel an app
    • Accounting - United Arab Emirates
    • CRM
    • Social Sales Channels
    • Messenger and WhatsApp
  1. Documentation
  2. Developers
  3. Headless Storefront API

Headless Storefront API

On this page
  • Storefront access tokens
  • Allowed origins
  • Endpoints
  • Cart and checkout
  • Errors, limits and caching
  • See also

The Storefront API is for developers who want their own front end, for example a Next.js site or a phone app, while Kartlo.App keeps the catalog, the cart and the checkout. It reads only what is published on your storefront.

Important

The Storefront API is included on the Pro plan and above, like the API and webhooks.

Storefront access tokens#

  1. Go to Settings › Developers and click Create storefront token.
  2. Name it and list the websites allowed to call it from a browser, one per line, for example https://www.example.com.
  3. Copy the token. Kartlo.App shows it once.

Tokens start with kartlo_pk_. They can only read published data and build carts, so they are safe in browser code. They cannot read orders, customers or stock. Send the token as X-Kartlo-Storefront-Access-Token or as a Bearer token.

Tip

Rotate makes a new token and the old one stops working within a minute. Revoke stops it for good.

Allowed origins#

A browser call is answered only when its site is on the token's list. Calls from a server or a phone app send no origin and are always answered. Use http:// only for localhost.

Note

Leave the list empty if only your server will call the API.

Endpoints#

All paths start with https://kartlo.app/api/storefront/v1.

Method and pathReturns
GET /shopStore name, currency, language, contact details, payment methods, policy pages and theme colors and fonts.
GET /productsProducts. Filters: q, vendor, price_min, price_max, available. Sort: newest, price_asc, price_desc, title. limit 1 to 48, page.
GET /products/{handle}One product with images, options, variants and buyer inputs.
GET /collectionsCollections with their product counts.
GET /collections/{handle}One collection, its products, vendor and price facets.
GET /menusThe navigation menu and published pages.
GET /pages/{handle}One page with its content.
GET /blogsBlog posts, when the Blogs app is on. Filters: category, tag, q.
GET /blogs/{handle}One post with the previous, next and related posts.
POST /cartsA new cart, optionally with lines.
GET /carts/{cartId}The cart with lines, subtotal and discounts.
POST /carts/{cartId}/linesAdds a variant: variant_id, quantity, properties.
PATCH /carts/{cartId}/lines/{lineId}Changes the quantity. 0 removes the line.
DELETE /carts/{cartId}/lines/{lineId}Removes the line.
POST /carts/{cartId}/discountApplies a discount code.
DELETE /carts/{cartId}/discountRemoves the discount code.
POST /carts/{cartId}/checkoutA checkout_url that opens your hosted checkout with this cart.
const API = 'https://kartlo.app/api/storefront/v1';
const TOKEN = 'kartlo_pk_...';
const sf = (path, init = {}) =>
  fetch(API + path, {
    ...init,
    headers: { 'X-Kartlo-Storefront-Access-Token': TOKEN, 'Content-Type': 'application/json', ...init.headers },
  }).then((r) => r.json());
const { shop } = await sf('/shop');
const { products, page_count } = await sf('/products?sort=price_asc&available=true&limit=12');
const { product } = await sf('/products/oud-oil');
const { collection, products: inCollection } = await sf('/collections/summer?page_size=24');
const { menu } = await sf('/menus');
const { page } = await sf('/pages/about-us');
const { posts } = await sf('/blogs?category=news');

Cart and checkout#

The cart is kept by Kartlo.App. Save its id in your site, for example in local storage. Delivery and tax are worked out at checkout. The checkout URL opens your store's own checkout, so payments, delivery options and order emails work as usual.

let { cart } = await sf('/carts', { method: 'POST', body: JSON.stringify({}) });
({ cart } = await sf(`/carts/${cart.id}/lines`, {
  method: 'POST',
  body: JSON.stringify({ variant_id: product.default_variant_id, quantity: 1 }),
}));
({ cart } = await sf(`/carts/${cart.id}/lines/${cart.lines[0].id}`, { method: 'PATCH', body: JSON.stringify({ quantity: 2 }) }));
({ cart } = await sf(`/carts/${cart.id}/discount`, { method: 'POST', body: JSON.stringify({ code: 'SAVE10' }) }));
const { checkout_url } = await sf(`/carts/${cart.id}/checkout`, { method: 'POST' });
window.location.href = checkout_url;

Errors, limits and caching#

An error answer has error.code and error.message.

StatusMeaning
401The token is missing, wrong or revoked.
402The store is not on the Pro plan or above.
403The browser site is not on the token’s list, or the store is password protected or closed.
404No such product, collection, page, post or cart in this store.
422The cart action was refused, for example out of stock or a code that does not apply. The message says why.
429Too many requests. Each token can make 3,000 requests a minute, and each visitor 300.

Catalog answers are cached for up to a minute, so changes in your dashboard show within about a minute. Searches and carts are never cached. Filtered and searched product lists cover your newest 250 products.

See also#

  • API and webhooks
PreviousAPI and webhooksNextKartlo Apps

On this page

  • Storefront access tokens
  • Allowed origins
  • Endpoints
  • Cart and checkout
  • Errors, limits and caching
  • See also
FeaturesPricingDocsContactPrivacyTerms© 2026 Louward Labs FZC LLC