Official JavaScript/TypeScript SDK for Sazito storefronts.
This SDK is built for application developers who want a typed, framework-agnostic client with:
- automatic request/response key transformation
- unified response objects (
{ data, error }) - configurable retry/timeout/cache behavior
- guest checkout credential handling
- modular API access for products, cart, invoices, shipping, payments, user, CMS, analytics, and more
- Name:
@sazito/client-sdk - Version: See
package.json - License:
MIT
- Node.js 18+ (recommended) or any runtime with
fetch - Browser environments with
fetch
npm install @sazito/client-sdkyarn add @sazito/client-sdkpnpm add @sazito/client-sdkimport { createSazitoClient } from '@sazito/client-sdk';
const sazito = createSazitoClient({
domain: 'mystore.sazito.com'
});
const res = await sazito.products.list({
page: 1,
pageSize: 20,
sort: 'newest'
});
if (res.error) {
console.error(res.error.message, res.error.status);
} else {
console.log(res.data.items);
}All SDK methods return a SazitoResponse<T>:
type SazitoResponse<T> = {
data?: T;
error?: {
status?: number;
message: string;
type: 'network' | 'api' | 'validation';
details?: any;
};
};Typical usage:
const response = await sazito.categories.get(110);
if (response.error) {
// API/network/validation issue
return;
}
// success path
console.log(response.data);import { createSazitoClient } from '@sazito/client-sdk';
const sazito = createSazitoClient({
domain: 'mystore.sazito.com',
timeout: 30000,
debug: false,
retry: {
enabled: true,
retries: 3,
retryDelay: 1000
},
cache: {
products: { enabled: true, ttl: 600000 },
categories: { enabled: true, ttl: 600000 },
cart: { enabled: false },
orders: { enabled: false },
search: { enabled: true, ttl: 300000 },
cms: { enabled: true, ttl: 600000 },
tags: { enabled: true, ttl: 600000 },
entityRoutes: { enabled: true, ttl: 600000 }
}
});| Field | Type | Required | Notes |
|---|---|---|---|
domain |
string |
Yes | Store domain without protocol |
timeout |
number |
No | Global request timeout in ms (default 30000) |
retry |
object | No | Retry policy for 5xx responses |
cache |
object | No | Per-module cache strategy |
customFetchApi |
typeof fetch |
No | Override fetch implementation |
debug |
boolean |
No | Enables SDK debug logging |
Any API call can receive RequestOptions:
const response = await sazito.products.get('/product/sample-slug', {
cache: false,
timeout: 5000,
retries: 1,
headers: {
'X-Request-ID': 'req-123'
}
});Supported request options:
retriestimeoutcacheheaderssignal
sazito.setAuthToken('YOUR_JWT');
const isLoggedIn = sazito.isAuthenticated();
const token = sazito.getAuthToken();
sazito.clearAuth();Auth token behavior:
- SDK injects
Authorizationheader automatically when a token exists. - Token is sent as raw JWT (not
Bearer <token>). - Token is persisted under
user_id_tokeninlocalStorage(with cookie fallback).
sazito.clearCache();
sazito.clearCredentials();
sazito.clearAll();
sazito.cart.clearCart();
sazito.invoices.clearInvoice();
sazito.shipping.clearAddress();
sazito.payments.clearPayment();The client instance exposes:
productscategoriescartordersinvoicesshippingpaymentsuserssearchfeedbackswalletcmsimagesvisitsbookingentityRoutesmenugeneral
| Module | Methods |
|---|---|
products |
get, list, search |
categories |
get, list |
cart |
get, create, addItem, updateItem, removeItem, clearCart |
orders |
list, get |
invoices |
get, create, refresh, addShippingAddress, addDiscountCode, assignShippingMethod, addDetails, getApplicableShippingMethods, clearInvoice |
shipping |
createAddress, updateAddress, getAddress, getMethods, clearAddress |
payments |
getMethods, create, initialize, processStep, clearPayment |
users |
login, requestMobileOTP, verifyMobileOTP, requestEmailLogin, register, getCurrentUser, updateProfile, requestMobilePhoneUpdate, verifyMobilePhoneUpdate, forgotPassword, revivePassword, mergeUser |
search |
search |
feedbacks |
list, create, get |
wallet |
getBalance, applyCredit, removeCredit, listTransactions |
cms |
getPage, listPages, getBlogPost, listBlogPosts, listAll |
images |
upload, delete |
visits |
track, trackProduct, trackCategory |
booking |
listEvents, getEvent, createBooking, listBookings, cancelBooking |
entityRoutes |
resolve |
menu |
getHeaderMenu |
general |
getInfo, getFeatures, getCheckoutConfig, getWalletConfig, getTajrobeConfig |
const product = await sazito.products.get('/product/some-product-slug');
const list = await sazito.products.list({
categories: [73, 94],
priceMin: 100000,
priceMax: 900000,
availableOnly: true,
discountedOnly: true,
sort: '!price',
page: 1,
pageSize: 12
});
const search = await sazito.search.query('shoes', {
categoryId: 73,
minPrice: 100000,
maxPrice: 900000,
page: 1,
pageSize: 10
});// 1) Add product to cart
const cartRes = await sazito.cart.addItemWithAttributes(12345, 2);
if (cartRes.error) throw new Error(cartRes.error.message);
// 2) Create invoice from cart
const invoiceRes = await sazito.invoices.create();
if (invoiceRes.error) throw new Error(invoiceRes.error.message);
// 3) Add shipping address
const addrRes = await sazito.shipping.createAddress({
firstName: 'John',
lastName: 'Doe',
mobilePhone: '09123456789',
regionId: 1,
cityId: 10,
address: 'No. 10, Example St',
postalCode: '1234567890'
});
if (addrRes.error) throw new Error(addrRes.error.message);
// 4) Attach shipping address to invoice
const attachRes = await sazito.invoices.addShippingAddress(addrRes.data.id, addrRes.data.identifier);
if (attachRes.error) throw new Error(attachRes.error.message);
// 5) Fetch methods and assign shipping
const methodsRes = await sazito.invoices.getApplicableShippingMethods();
if (methodsRes.error) throw new Error(methodsRes.error.message);
if (methodsRes.data?.itemsShippingRate?.length) {
const assignments = methodsRes.data.itemsShippingRate.map((entry) => ({
rateId: entry.shippingRate.id,
invoiceItemIds: [entry.invoiceItemId],
}));
const assignRes = await sazito.invoices.assignShippingMethod(assignments);
if (assignRes.error) throw new Error(assignRes.error.message);
}
// 6) Payment
const paymentMethods = await sazito.payments.getMethods();
if (paymentMethods.error) throw new Error(paymentMethods.error.message);
if (paymentMethods.data?.length) {
const paymentCreateRes = await sazito.payments.create(paymentMethods.data[0].id);
if (paymentCreateRes.error) throw new Error(paymentCreateRes.error.message);
const action = await sazito.payments.initialize();
if (action.error) throw new Error(action.error.message);
console.log(action.data);
}const login = await sazito.users.login({
email: 'dev@example.com',
password: 'strong-password'
});
if (login.data?.jwt) {
sazito.setAuthToken(login.data.jwt);
}
const me = await sazito.users.getCurrentUser();const route = await sazito.entityRoutes.resolve('/product/some-product-slug');
const page = await sazito.cms.getPage('/about-us');
const blog = await sazito.cms.getBlogPost('/blog/how-to-buy');const menu = await sazito.menu.getHeaderMenu();
const info = await sazito.general.getInfo();
const features = await sazito.general.getFeatures();await sazito.visits.track();The SDK transforms request and response keys to improve developer ergonomics.
Common examples:
no_of_items->quantitysingle_item_price->unitPriceproduct_variant_id->variantIdfirst_name->firstNamepostal_code->postalCode
Notes:
- Request payloads are transformed before being sent.
- Response payloads are transformed before being returned.
- Some APIs accept both SDK-friendly and raw fields for backward compatibility.
Run the local visual playground:
pnpm visual:apisThen open:
http://127.0.0.1:4173
Files:
scripts/visual-docs-server.jsscripts/visual-api-playground/public/index.htmlscripts/visual-api-playground/public/app.jsscripts/visual-api-playground/public/styles.css
Project scripts:
pnpm build # Build dist outputs
pnpm dev # Rollup watch mode
pnpm typecheck # TypeScript check (no emit)
pnpm lint # ESLint on src/
pnpm validate # typecheck + lintSDK docs are implemented as a separate Fumadocs app in docs/.
Run docs locally from the repository root:
pnpm docs:install
pnpm docs:devBuild/start docs:
pnpm docs:build
pnpm docs:startThis docs app is tracked in GitHub, but it is not included in the published npm package.
Publishing is controlled by the root files list in package.json, which only ships:
dist/README.mdLICENSE
Relevant docs routes:
app/docs/[[...slug]]for the rendered docs pagesapp/llms-docs/[[...slug]]for markdown-friendly LLM exports (/docs/*.mdxrewrite target)app/llms.txtandapp/llms-full.txtfor index/full LLM text exports
Output formats:
dist/index.js(CJS)dist/index.esm.js(ESM)dist/index.umd.js(UMD)dist/index.d.ts(types)
src/
api/ API modules
core/ client, config, HTTP layer, cache
constants/ endpoint constants
types/ exported SDK types
utils/ token storage, credentials, transformers
scripts/
visual-docs-server.js
visual-api-playground/public/
docs/
app/ Next.js routes and layouts
content/docs/ MDX documentation pages
lib/ Fumadocs source/layout configUsually means prerequisite state is missing (for example no cart/invoice credentials in guest flow). Initialize earlier steps first.
Check connectivity, runtime fetch support, and request timeout.
Make sure token is set with setAuthToken and that your backend accepts raw JWT in Authorization.
cms.getPage / cms.getBlogPost validate entity type and can throw when URL resolves to another entity type. Wrap these calls in try/catch.
import { createSazitoClient, SazitoResponse, Product } from '@sazito/client-sdk';
const client = createSazitoClient({ domain: 'mystore.sazito.com' });
async function getProduct(path: string): Promise<Product | null> {
const res: SazitoResponse<Product> = await client.products.get(path);
return res.data ?? null;
}