API - Overview

API - Connection and authorization

Set up API keys, test the connection and learn how to handle errors and request limits.

Endpoint overview

MethodEndpointDescriptionAccess
GET/public-api/healthzService health check.public
GET/public-api/v1/auth/checkValidates credentials and returns storefront, scopes and plan capabilities.any authenticated credential

Authentication and base URL

https://alterproduct.com/public-api/v1

Create API credentials in the e-commerce settings panel. The Access Token is shown once, so store it immediately in your backend secret storage.

Keep the Access Key and Access Token on your server. Authenticated endpoints reject browser-origin calls that include Origin or Referer headers.

Credentials can be scoped. Use GET /auth/check to verify the active storefront, plan capabilities and scopes returned for the credential.

x-alter-access-key: YOUR_API_KEY
x-alter-access-token: YOUR_API_TOKEN
ParameterRequiredDetails
x-alter-access-keyyesPublic credential identifier.
x-alter-access-tokenyesSecret token paired with the access key.
x-alter-client-fingerprintnoOptional stable fingerprint for embed session rate limiting.
Authorizationruntime onlyBearer token returned by POST /embed/session, used by /runtime/bootstrap.

Connection test

Use the auth check endpoint before enabling synchronization or embed features in a live integration.

GET https://alterproduct.com/public-api/v1/auth/check

Example request (fetch)

const response = await fetch('https://alterproduct.com/public-api/v1/auth/check', {
  method: 'GET',
  headers: {
    'x-alter-access-key': process.env.ALTER_ACCESS_KEY,
    'x-alter-access-token': process.env.ALTER_ACCESS_TOKEN
  }
});

const payload = await response.json();

if (!response.ok) {
  throw new Error(payload?.code || payload?.error || `Alter API ${response.status}`);
}

console.log(payload);

Example response

{
  "ok": true,
  "message": "success",
  "storefrontId": 12,
  "userOwnerId": 34,
  "credentialId": 56,
  "scopes": ["orders:read", "orders:write", "products:read"],
  "plan": {
    "requiredPlan": "Business",
    "currentPlanName": "Business",
    "eligible": true,
    "runtimeFlags": {
      "viewer": true,
      "configurator": true,
      "customizer": true
    },
    "limits": {
      "activeRuntimeBindingsLimit": 100,
      "monthlyReassignmentLimit": 1000,
      "monthlyEmbedTokenLimit": 50000
    }
  }
}

The helper below is used by the remaining examples. It is plain fetch and can run in Node.js 18+ or any server runtime that provides fetch.

const ALTER_API_BASE = 'https://alterproduct.com/public-api/v1';

const authHeaders = {
  'x-alter-access-key': process.env.ALTER_ACCESS_KEY,
  'x-alter-access-token': process.env.ALTER_ACCESS_TOKEN
};

async function alterFetch(path, options = {}) {
  const response = await fetch(`${ALTER_API_BASE}${path}`, {
    ...options,
    headers: {
      ...authHeaders,
      ...(options.body ? { 'Content-Type': 'application/json' } : {}),
      ...options.headers
    }
  });

  const payload = await response.json().catch(() => null);

  if (!response.ok) {
    throw new Error(payload?.code || payload?.error || `Alter API ${response.status}`);
  }

  return payload;
}

Errors and rate limits

Most controller errors are normalized to a code response. Authentication middleware and rate limiters can return an error response instead.

// Controller error
{
  "code": "assetCatalog.invalidType"
}

// Auth middleware or rate limit
{
  "error": "Unauthorized"
}

{
  "error": "Too Many Requests"
}
TypeLimitWindow
Global600 requests60 seconds
GET /auth/check60 requests60 seconds
Orders read/products read300 requests60 seconds
Orders write/embed sessions/runtime bindings120 requests60 seconds
Assets/design imports read180 requests60 seconds
Fonts300 requests60 seconds
WP connect exchange30 requests60 seconds
GET /model-generator/*600 requests60 seconds