Skip to content

js-api-client

Terminal window
npx skills add https://github.com/crystallizeapi/ai --skill js-api-client

Crystallize JS API Client

The @crystallize/js-api-client package provides typed utilities for working with all Crystallize APIs in JavaScript/TypeScript environments.

Consultation Approach

Before writing code, understand the context. Ask clarifying questions:

  1. What are you trying to do? Read data, write data, manage carts, handle webhooks?
  2. Do you need raw GraphQL or a high-level helper? Helpers reduce boilerplate for common workflows (orders, carts, navigation). Use raw GraphQL via API callers for custom queries or when helpers don’t cover the use case.
  3. Which API? Catalogue/Discovery for storefront reads, PIM for admin writes, Shop Cart for checkout flows.
  4. What auth do you have? staticAuthToken is enough for read-only. PIM/Shop operations need accessTokenId + accessTokenSecret. For plugins or delegated calls where the caller already holds a JWT, pass it as bearerToken — it becomes Authorization: Bearer <jwt>.
  5. Is this server-side or client-side? The client works in both, but credentials should only live server-side.

Installation

Terminal window
pnpm add @crystallize/js-api-client
# or npm install @crystallize/js-api-client
# or yarn add @crystallize/js-api-client

Quick Start

import { createClient } from "@crystallize/js-api-client";
const api = createClient({
tenantIdentifier: "your-tenant",
// For protected APIs, provide credentials:
// accessTokenId: '…',
// accessTokenSecret: '…',
// staticAuthToken: '…', // for read-only catalogue/discovery
// bearerToken: '…', // JWT sent as `Authorization: Bearer <jwt>` (e.g. plugin backendToken)
});
// Call any GraphQL API with string queries
const { catalogue } = await api.catalogueApi(
`query Q($path: String!, $language: String!) {
catalogue(path: $path, language: $language) {
name
path
}
}`,
{ path: "/shop", language: "en" },
);
// Close when using HTTP/2 option
api.close();

Configuration

createClient(configuration, options?)

Configuration Options

OptionDescription
tenantIdentifierRequired. Your tenant name
tenantIdOptional tenant ID
accessTokenId / accessTokenSecretFor PIM/Shop operations
sessionIdAlternative to token-based auth
staticAuthTokenFor read-only catalogue/discovery
bearerTokenJWT forwarded as Authorization: Bearer <jwt> (e.g. a plugin backendToken)
shopApiTokenAuto-fetched if not provided
shopApiStagingUse staging Shop API
originCustom host suffix (default: .crystallize.com)

Client Options

OptionDescription
useHttp2Enable HTTP/2 transport
profilingProfiling callbacks for debugging
extraHeadersExtra request headers for all calls
shopApiTokenControl auto-fetch behavior

API Callers

All callers share the same signature:

<T>(query: string, variables?: Record<string, unknown>) => Promise<T>;
CallerPurpose
catalogueApiCatalogue GraphQL
discoveryApiDiscovery GraphQL (search/browse)
pimApiPIM GraphQL (legacy — prefer nextPimApi)
nextPimApiPIM Next GraphQL (scoped to tenant, recommended)
meApiPer-user GraphQL (@me) — call on behalf of the authenticated viewer
shopCartApiShop Cart GraphQL (token auto-handled)

High-Level Helpers

Available helpers (see High-Level Helpers Reference for full examples):

HelperImportPurpose
createCatalogueFetcher@crystallize/js-api-clientBuild typed catalogue queries with object syntax
createNavigationFetcher@crystallize/js-api-clientFetch navigation trees by depth
createProductHydrater@crystallize/js-api-clientFetch products/variants by path or SKU
createOrderFetcher@crystallize/js-api-clientFetch orders with type-safe field selection
createOrderManager@crystallize/js-api-clientCreate/update orders, set payments, move pipeline stages
createCustomerManager@crystallize/js-api-clientCreate and update customers
createCustomerGroupManager@crystallize/js-api-clientManage customer groups
createSubscriptionContractManager@crystallize/js-api-clientCreate and manage subscription contracts
createCartManager@crystallize/js-api-clientHydrate carts, add items, place orders (token auto-handled)

Authentication

Auth TypeHeader sentUse Case
staticAuthTokenX-Crystallize-Static-Auth-Token: <token>Read-only catalogue/discovery
accessTokenId + accessTokenSecretX-Crystallize-Access-Token-Id + X-Crystallize-Access-Token-SecretPIM/Shop operations
sessionIdCookie: connect.sid=<sessionId>Alternative to token pair
bearerTokenAuthorization: Bearer <jwt>JWT-based auth — plugins forward envelope.backendToken; delegated/per-user calls
shopApiTokenAuthorization: Bearer <token> (Shop API only)Optional; auto-fetched if omitted

Priority when multiple are set on the same client: sessionId > bearerToken > staticAuthToken > accessTokenId/accessTokenSecret. Only one is sent per request. Per-caller restrictions:

  • discoveryApi only honors bearerToken and staticAuthToken.
  • catalogueApi honors bearerToken, staticAuthToken, and accessTokenId/accessTokenSecret.
  • pimApi, nextPimApi, and meApi honor sessionId, bearerToken, and accessTokenId/accessTokenSecret.

Generate access tokens in the Crystallize App: Settings → Access Tokens. For plugin-issued JWTs, use the backendToken from the decrypted iframe/webhook payload — see the plugins skill.

Example: bearer-token client (plugin context)

import { createClient } from "@crystallize/js-api-client";
const api = createClient({
tenantIdentifier,
bearerToken: decoded.envelope.backendToken, // RS256 JWT from the plugin payload
});
const { tenant } = await api.nextPimApi<{ tenant: { id: string; name: string } }>(
"{ tenant { ... on Tenant { id name } } }",
);

References


Crystallize AI