One instance, four calls, one 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.
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.

Types

Errors

Visitor and storage

Signals