Appearance
Authentication
The Shopwave API uses OAuth2 with the authorization code flow. Every API request must include a valid Bearer token in the Authorization header.
Overview
mermaid
sequenceDiagram
participant App as Your App
participant User as Merchant User
participant Auth as Shopwave Auth
participant API as Shopwave API
App->>User: Redirect to authorization URL
User->>Auth: Grant access
Auth->>App: Redirect with authorization code
App->>Auth: Exchange code for tokens
Auth->>App: Access token + refresh token
App->>API: API request with Bearer token
API->>App: Response dataStep 1: Redirect to authorize
Send the merchant to the Shopwave Auth authorization endpoint:
https://secure.staging.merchantstack.com/oauth/authorize
?client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=read write| Parameter | Description |
|---|---|
client_id | Your application's identifier from the Applications API |
redirect_uri | Must match one of the URLs registered with your application |
response_type | Always code |
scope | Space-separated list of scopes |
The merchant reviews the requested permissions and either approves or denies access.
Step 2: Exchange the code
After approval, Shopwave Auth redirects the merchant back to your redirect_uri with a code query parameter:
https://yourapp.com/callback?code=AUTHORIZATION_CODEExchange this code for an access token:
bash
curl -X POST https://secure.staging.merchantstack.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "AUTHORIZATION_CODE",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://yourapp.com/callback"
}'js
const response = await fetch('https://secure.staging.merchantstack.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'authorization_code',
code: 'AUTHORIZATION_CODE',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
redirect_uri: 'https://yourapp.com/callback'
})
})
const tokens = await response.json()
// {
// access_token: "eyJhbGciOi...",
// refresh_token: "dGhpcyBpcyBh...",
// token_type: "Bearer",
// expires_in: 3600
// }WARNING
Authorization codes are single-use and short-lived. Exchange them promptly — typically within 60 seconds.
Step 3: Use the token
Include the access token as a Bearer token in the Authorization header of every API request:
bash
curl https://api.staging.merchantstack.com/product \
-H "Authorization: Bearer eyJhbGciOi..." \
-H "x-accept-version: 2.0"js
const response = await fetch('https://api.staging.merchantstack.com/product', {
headers: {
'Authorization': 'Bearer eyJhbGciOi...',
'x-accept-version': '2.0'
}
})Scopes
Request only the scopes your application needs. The merchant sees these during the approval step.
| Scope | Allows |
|---|---|
read | Read access to all resources — products, baskets, stores, reports, etc. |
write | Create and update resources — products, baskets, transactions, invoices, etc. |
admin | Full administrative access including destructive operations (deletes) |
TIP
The admin scope includes write, and write includes read. Request the minimum scope your application requires — merchants are more likely to approve limited access.
Refreshing tokens
Access tokens expire after a set period. Use the refresh token to obtain a new access token without requiring the merchant to re-authorize:
bash
curl -X POST https://secure.staging.merchantstack.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "dGhpcyBpcyBh...",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'js
const response = await fetch('https://secure.staging.merchantstack.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token: 'dGhpcyBpcyBh...',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET'
})
})
const tokens = await response.json()
// New access_token and refresh_tokenWARNING
Each refresh token is single-use. The response includes a new refresh token — store it securely and discard the old one.
Common errors
| Error | Cause | Fix |
|---|---|---|
401 Unauthorized | Missing or invalid token | Check the Authorization header format: Bearer <token> |
401 Unauthorized | Expired token | Refresh the token using the refresh flow above |
403 Forbidden | Insufficient scope | Your token's scope doesn't cover this operation — re-authorize with the required scope |
invalid_grant | Expired or reused authorization code | Restart the authorization flow from Step 1 |
invalid_client | Wrong client_id or client_secret | Verify your application credentials in the partner dashboard |
redirect_uri_mismatch | Redirect URI doesn't match | The redirect_uri must exactly match one registered with your application |
Security best practices
- Store tokens securely — never expose tokens in client-side code, URLs, or logs
- Use HTTPS — all Shopwave Auth and API endpoints require HTTPS
- Rotate secrets — if your client secret is compromised, regenerate it immediately via the Applications API
- Minimal scopes — request only what your application needs; you can always re-authorize for additional scopes later
- Validate redirect URIs — register only the specific callback URLs your application uses