track and a few loose pieces. The
types come from the OpenAPI contract and are never written by hand: if the contract
changes, the package changes with it.
createStorefront(options): Storefront
The instance:
The options
Only the first two are required.string
required
The
spk_… key you copy from the admin. Why it can be public: Keys and security.string
required
Your store’s connection (
cn_…). It is validated against the key’s store.string
default:"https://api.crossup.ai/salespilot"
The API endpoint. In production,
https://salespilot.crossup.ai.typeof fetch
Your own
fetch, for tests or for a runtime without a global fetch.boolean
default:"true"
true stores it in localStorage and a cookie, mirrored. false keeps it in memory: it still travels, but every load is a new visitor. Use it without consent.VisitorStorage
Your own storage. Wins over
persistVisitor.string
Cookie domain (
.mystore.com): the same visitor across all subdomains.(() => Visitor | undefined) | false
Your own visitor, for those who already resolved it (a server).
false sends no visitor in any request.(error: unknown) => void
Called when the visitor couldn’t be resolved and the request went out without it. Never called with an API error.
(() => ClientContext | undefined) | false
The browser context (page, referrer, UTM, language, screen). By default it is read on every request;
false doesn’t send it; a function replaces it. It never breaks the request.(error: unknown) => void
Every signal that couldn’t be built, that the server rejected, that was dropped on a
4xx or that fell out of the full queue. Never called for a retry.(result, signal) => void
Every server response to a signal:
accepted, duplicate or rejected.SignalOptions
How signals are batched and retried:
flushIntervalMs (2000), maxQueueSize (200), maxBackoffMs (60000), storage. See Report signals.