Connection
POST /v1/shop/connection declares your shop to ShopiMind: its currency, languages, timezone, and the root of the URLs ShopiMind will call back. It is the first call any connector makes, and the only one required before you can push anything.
The two identifiers
| Where to find it | Role | |
|---|---|---|
API key: {prefix}.{secret} | Shop settings → API access, at generation (shown once) | Authenticates every call, via the spm-api-key header. Resolves the shop. |
Shop identifier: e.g. SPM123456 | Shop settings → API access, dedicated panel | Identifies the shop. Sent as client-id here, passed to spm('init', …) in tracking, and returned by ShopiMind in every inbound callback. |
The shop identifier is generated once, when the shop is created. There is no partner enrolment process to go through: if you have access to the shop, you already have everything you need.
The identifier is not a secret
It is public by design, the tracking script exposes it in plain text in the shop's HTML. The secret is the API key. Do not treat them the same way.
The four headers
The three client-* headers add to spm-api-key, they do not replace it. A missing spm-api-key returns 401; a missing one of the other three returns 400 Missing required headers.
| Header | Example | Role |
|---|---|---|
spm-api-key | a1b2c3d4.xK9p… | Authentication. Resolves the target shop. |
client-id | SPM123456 | Shop identifier. Re-checked server-side: the request is rejected if it does not match the shop resolved from the key. |
client-version | 1.0.0 | Version of your connector. Free-form string. Surfaced in our support tooling. |
current-build | 1 | Build number of your connector. Free-form string holding an integer. |
client-version and current-build have no functional effect: they exist for diagnostics. Bump them on every release, that is how we know which version runs at a merchant when you call us.
The body
{
// Required
"default_currency": "EUR", // ISO 4217
"default_lang": "fr", // ISO 639-1
"langs": ["fr", "en"], // ISO 639-1, COMPLETE list, see below
"timezone": "Europe/Paris", // IANA
"url_client": "https://connector.my-shop.com/shopimind",
"ecommerce_version": "1.0.0", // version of YOUR platform
"module_version": "1.0.0", // version of YOUR connector
// Optional
"shop_id": "1" // multi-store, see below
}| Field | Format | Notes |
|---|---|---|
default_currency | ISO 4217 | Default display currency. |
default_lang | ISO 639-1 | Must appear in langs. |
langs | ISO 639-1 array | Authoritative, see the warning below. |
timezone | IANA (Europe/Paris) | Drives send-time computation and cart timestamps. A non-IANA identifier will skew every date you have. |
url_client | absolute URL | Root of inbound callbacks. See below. |
ecommerce_version | free-form string | Shop platform version. |
module_version | free-form string | Your connector's version. |
shop_id | string | Only for multi-store setups. |
langs is destructive
The array is authoritative: any language already registered for the shop and absent from langs is deleted, and default_lang rewrites the "default language" flag. Always send the complete list of active languages, never a delta.
url_client: the callback root
This field is not informational. It is the root from which ShopiMind builds the URL of each of its inbound calls:
| Action | URL built |
|---|---|
| Generate vouchers | POST {url_client}/vouchers |
| Create a customer account | POST {url_client}/customers |
| Newsletter opt-in | POST {url_client}/subscribe-customer |
Three rules to respect:
- Point it at the service hosting your connector, not at the storefront. If your front end is headless on
www.my-shop.comand your connector lives on a separate API,url_clientmust target the API. - No redirect. ShopiMind follows same-site redirects preserving method and body, but refuses any cross-origin redirect (the body is signed; replaying it elsewhere would be a vulnerability) and any redirect to
/. Serve the exact URL: watch out for trailing slashes,http→httpsandapex→www. - HTTPS in production.
You are not required to implement every route. Expose the ones whose features you want, see Inbound callbacks.
Side effects
Two consequences of this call, worth knowing before you wire it.
The key used becomes the primary key
The call marks the key that issued it as the shop's primary key, and removes that status from every other key. And it is the primary key's secret that signs inbound callbacks (→ Signature).
In other words: only ever call /shop/connection with the key dedicated to your connector. If you test with another key, that one becomes primary, and the signature your connector verifies no longer matches the one ShopiMind emits, your callbacks will return Unauthorized with no obvious cause.
Reconnecting is idempotent… except for langs
Replaying the call with the same configuration breaks nothing. Replaying it with a truncated langs deletes languages. Replaying it with another key changes the signing key.
Multi-store
If your platform hosts several shops under one installation, each is a distinct ShopiMind shop, with its own API key and its own identifier.
Set shop_id to your internal shop identifier. ShopiMind stores it and returns it in every inbound callback under the shopIdShop key, letting you route the call to the right shop and resolve the right credentials there.
{
"shop_id": "3",
"default_currency": "EUR"
// …
}On the connector side, resolve credentials per shop: read shopIdShop from every callback body and use the matching shop's credentials, falling back to your global configuration when the field is absent.
When to replay the connection
| Event | Replay? |
|---|---|
| Connector installation | Yes |
| Language added/removed, currency or timezone changed | Yes |
| Connector URL changed | Yes: otherwise callbacks go nowhere |
| Connector update | Yes, refreshes module_version / current-build |
| API key rotation | Yes, with the new key: otherwise callback signing stays on the old one |
| Every process start | No, it is a configuration call, not a ping |