Scope & versions
@shopimind/sdk-js is the official JavaScript/TypeScript client for the ShopiMind API. This page describes precisely its role (and its limits), its runtime compatibility and its versioning policy.
What the SDK does: outbound transport
The SDK is an outbound HTTP client: your code calls the ShopiMind API. It does not listen for or receive anything — it emits requests to https://core.shopimind.com/v1.
import { SpmClient, SpmCustomers } from '@shopimind/sdk-js';
// Client for the v1 API, authenticated with the shop's API key (spm-api-key header)
const client = SpmClient.getClient('v1', process.env.SHOPIMIND_API_KEY!);
// Read — paginated list
const res = await SpmCustomers.list(client, { limit: 50 });
if (!res.ok) {
throw new Error(res.error.message); // the SDK never throws: check res.ok
}
console.log(res.data.data); // ⚠️ business payload double-nested: res.data.data
// Bulk write with automatic chunking
const saved = await SpmCustomers.bulkSave(client, customers, { chunk: true });In practice, the SDK provides:
- E-commerce synchronization — customers, products, orders, vouchers, and their sub-resources (addresses, images, variations, carriers, statuses, categories, manufacturers).
- Reads —
get/list/getByReference/listGroupsdepending on the resource. - Custom data — definitions and records (custom data).
- Contacts — profiles, lists, tags, consent history, rejected messages (read-only).
- Events, lists, custom KPIs and carts (read-only).
- Shop connection, data sources and integration configuration.
The full list of resources and methods: → Resources & methods.
Authentication: a single direction
The SDK sends the shop API key in the spm-api-key header. This is the only key it handles, and it is used solely for outbound traffic (your code → ShopiMind). See → Authentication.
Verifying inbound requests: two primitives
The transport described above is outbound (your code → ShopiMind). For inbound requests (ShopiMind → your code), the SDK provides two signature-verification primitives — one per channel. Pick the one matching who emits the request.
SpmRequestValidator — connector channel (CMS modules)
When ShopiMind calls your CMS module (data sync, voucher generation…), it signs the body with an "imploded" scheme: the body is sorted at the first level, run through HMAC-SHA256 (key = sha256(secret)), then compared as md5 in constant time. The signature arrives in the Shopimind-Token header and the client id in Shopimind-Client-Identifiant.
import { SpmRequestValidator } from '@shopimind/sdk-js';
// CMS modules send a form-urlencoded body → parse it first.
const body = SpmRequestValidator.parseFormData(rawBody);
const { valid, error } = SpmRequestValidator.validateRequest({
clientId: headers['shopimind-client-identifiant'],
hmacToken: headers['shopimind-token'],
body,
apiIdentification: config.clientId, // id configured in the module
apiPassword: config.apiKey, // the shop's API key
});
if (!valid) {
// error: 'Invalid HMAC token', 'Invalid client ID', 'Missing … header'… → respond 401
return;
}
// → authenticated request: handle it.parseFormData also drops dangerous keys (__proto__, constructor, prototype) — a defense against prototype pollution.
SpmWebhookSignature — integration channel (webhooks)
When ShopiMind sends a webhook to your integration (activation, deactivation, lifecycle events…), it signs ${timestamp}.${rawBody} with HMAC-SHA256. Verification is timestamped: a tolerance window (anti-replay) rejects requests that are too old, and the comparison is timing-safe.
import { SpmWebhookSignature } from '@shopimind/sdk-js';
const result = SpmWebhookSignature.verifyFromHeaders(
rawBody, // the RAW body string — never the already-parsed object
headers,
webhookSecret, // the integration's shared secret
{
timestampHeader: 'x-shopimind-timestamp',
signatureHeader: 'x-shopimind-signature',
toleranceSeconds: 300, // anti-replay window (default: 300s)
},
);
if (!result.ok) {
// result.reason: 'signature_mismatch', 'timestamp_out_of_tolerance', 'missing_signature_headers'…
return; // → respond 401
}
// → authenticated webhook.Verify the RAW body
SpmWebhookSignature computes the signature over the raw string received. Verify it before any JSON parsing (or keep the original string): re-parsing then re-serializing changes the bytes and invalidates the signature.
Recap — three cases
- Outbound (your code → ShopiMind): the SDK sends the
spm-api-keykey. - Inbound — connector (ShopiMind → CMS module):
SpmRequestValidator(Shopimind-Token/Shopimind-Client-Identifiant). - Inbound — integration (ShopiMind → your integration):
SpmWebhookSignature(x-shopimind-timestamp/x-shopimind-signature).
The JavaScript integration kit relies on SpmWebhookSignature to verify integration webhooks automatically. See → Integration webhooks.
Compatibility
| Item | Support |
|---|---|
| Node.js | ≥ 18 (engines.node: >=18.17.0) |
| Modules | ESM only — import (no CommonJS build) |
| Language | TypeScript (bundled types) or JavaScript ESM |
| Runtime dependency | axios (single, installed automatically) |
| Targeted API version | v1 (via SpmClient.getClient('v1', …)) |
ESM only
@shopimind/sdk-js is distributed as pure ESM: it does not expose a CommonJS build. Use import { … } from '@shopimind/sdk-js'. A require(...) will fail — switch your project to ESM (the "type": "module" field in package.json) or use a dynamic import().
Detailed installation and prerequisites: → Installation.
Versions (SemVer)
The SDK follows semantic versioning MAJOR.MINOR.PATCH:
| Bump | When | Example |
|---|---|---|
| PATCH | Fix without API change | retry fix, typo |
| MINOR | Backward-compatible addition | new method, new option |
| MAJOR | Breaking change (signature, removal) | field rename, method removal |
The current version is 1.0.0. The public API is stable and follows full SemVer: no breaking change will land outside a major bump — pin a version for reproducible installs.
SDK and API versions
The SDK version (1.0.0) and the REST API version (v1, in the URL prefix) are independent. Updating the SDK does not change the API version you target via SpmClient.getClient('v1', …).