SeloraXDEVELOPERS

Client Credentials

Client Credentials

Client credentials provide server-to-server authentication for apps that need to make API calls without a user session. This is the simplest authentication method and works well for background processes, cron jobs, and webhook handlers.

Headers

Every request using client credentials must include all three headers:

X-Client-Id: sx_app_...
X-Client-Secret: sx_secret_...
X-Store-Id: 22
HeaderDescription
X-Client-IdYour app's client ID (issued on app creation)
X-Client-SecretYour app's client secret (issued on app creation)
X-Store-IdThe store ID to operate on (must have an active installation)

All three headers are required on every request. Omitting X-Client-Id or X-Client-Secret returns 401 Unauthorized. Omitting X-Store-Id returns 400 Bad Request.

When to Use Client Credentials

Use client credentials instead of OAuth Bearer tokens when:

  • Background jobs and cron tasks -- Your server needs to pull or push data on a schedule without merchant interaction
  • Webhook processing -- After receiving a webhook, your app needs to make API calls back to the platform to fetch additional data or update resources
  • Server-side integrations -- Backend services that interact with the SeloraX API without any user-facing flow
  • Initial setup before OAuth -- When bootstrapping an app's connection before the full OAuth flow is configured

Key Properties

  • Never expire -- Client credentials function like Shopify offline access tokens. Once issued, they remain valid until explicitly rotated.
  • Same API access as Bearer tokens -- Any endpoint accessible with an OAuth Bearer token can also be accessed with client credentials. The permission scope is determined by the app's installation.
  • Validated per-request -- The platform verifies the client ID, secret, and store ID on every request. No token storage or refresh logic is needed on your end.
  • All 3 headers required -- Unlike OAuth where a single Authorization header suffices, client credentials require all three headers to identify both the app and the target store.

Example

Node.js (fetch)

const response = await fetch('https://api.selorax.io/api/apps/v1/orders', {
  headers: {
    'X-Client-Id': process.env.CLIENT_ID,
    'X-Client-Secret': process.env.CLIENT_SECRET,
    'X-Store-Id': '22',
  },
});
 
const data = await response.json();
console.log(data);

Node.js (axios)

const axios = require('axios');
 
const client = axios.create({
  baseURL: 'https://api.selorax.io/api/apps/v1',
  headers: {
    'X-Client-Id': process.env.CLIENT_ID,
    'X-Client-Secret': process.env.CLIENT_SECRET,
    'X-Store-Id': process.env.STORE_ID,
  },
});
 
// Fetch orders
const { data } = await client.get('/orders');
 
// Update a product
await client.put('/products/123', {
  title: 'Updated Product Name',
  price: 29.99,
});

cURL

curl -X GET https://api.selorax.io/api/apps/v1/orders \
  -H "X-Client-Id: sx_app_1b16e193a28d2640d2d9734dbf4907e8" \
  -H "X-Client-Secret: sx_secret_dd0f155b..." \
  -H "X-Store-Id: 22"

Comparison: All Authentication Methods

MethodUse CaseExpiryHeadersBest For
OAuth BearerUser-initiated actions24 hoursAuthorization: Bearer sx_at_...Apps acting on behalf of a logged-in merchant
Session TokenIframe embedded apps10 minutesAuthorization: Bearer eyJ...Embedded app UI inside the dashboard
Client CredentialsServer-to-serverNeverX-Client-Id + X-Client-Secret + X-Store-IdBackground jobs, webhooks, cron tasks

Choosing the right method

  • If your app has a UI embedded in the dashboard, use Session Tokens for iframe authentication and API calls from the frontend.
  • If your app acts on behalf of a merchant who is actively using it, use the OAuth 2.0 flow to obtain Bearer tokens.
  • If your app runs server-side without user interaction, use Client Credentials.

Many apps use a combination: session tokens for the embedded UI, and client credentials for background processing.

Rotating Secrets

If your client secret is compromised, rotate it immediately:

POST /api/apps/:app_id/rotate-secret

Requires [auth, admin] middleware and the apps__manage_apps permission.

This generates a new client_secret and invalidates the old one. All requests using the old secret will fail immediately. The new secret is returned once in the response and cannot be retrieved again.

:::danger After rotating, update the secret in all your environments (production, staging, development) before the next API call. There is no grace period -- the old secret stops working immediately. :::

Security Best Practices

  • Never expose client_secret in frontend code. Client credentials are for server-to-server use only. If you need browser-side authentication, use Session Tokens.
  • Use environment variables. Store CLIENT_ID, CLIENT_SECRET, and STORE_ID in environment variables or a secrets manager. Never hard-code them.
  • Restrict network access. If possible, allowlist your server's IP addresses to limit where API calls can originate from.
  • Monitor usage. Watch for unexpected spikes in API calls that could indicate a leaked secret.
  • Rotate periodically. Even without a known compromise, rotating secrets on a regular schedule (e.g. quarterly) reduces risk.