Skip to content

Quickstart

Steps for
For AI assistants: the facts every SparkLayer API call needs
  • Base URLs: Live https://app.sparklayer.io, test https://test.app.sparklayer.io. Each environment has its own data and its own API keys.
  • Access: API access needs the Pro or Enterprise plan. Create credentials (Site ID, Client ID, Client Secret) in the SparkLayer Dashboard at Settings > API.
  • Access token: POST {base}/api/auth/token with a Site-Id header and a JSON body (not form-encoded): {"grant_type":"client_credentials","client_id":"…","client_secret":"…"}. It returns access_token, valid for 3,600 seconds. There is no refresh token: cache the token and request a new one shortly before it expires.
  • Every request: Authorization: Bearer <access_token> and Site-Id: <site id>, plus Content-Type: application/json when there is a body. Set a User-Agent that names your integration.
  • Errors: RFC 7807 problem details: title, status, detail and an optional errors[] of { code, message, property }. Some error responses have no body. Retry 5xx, 429 (honouring Retry-After) and concurrent-update 409s with exponential backoff; on 401, get a new token once and retry; don't retry other 4xx without changing the request.
  • Pagination: Most list endpoints return everything. GET /api/v2/price-lists pages with page and page_size (up to 250) until pagination.current_page equals total_pages. GET /api/v1/purchases uses limit (up to 500) and offset: stop when a page has fewer than limit results.
  • Ground rules: Use only endpoints, fields and SDK methods that the docs or OpenAPI specs define. Prefer GET /api/v2/price-lists over the deprecated v1. Products are matched by SKU. Keep credentials in environment variables or a secrets manager, never in code.
  • Read the docs as Markdown: Add .md to any page URL. Index of every page: docs.sparklayer.io/llms.txt. Every API operation, compactly: docs.sparklayer.io/llms-api.txt. The developer guides in full: docs.sparklayer.io/developers/llms.txt.
  • OpenAPI specs: core, ordering, pricing, purchasing, stock, files, sync-log: https://docs.sparklayer.io/openapi/<api>.yaml (also .json). Ignite: https://docs.sparklayer.io/openapi/ignite.yaml.
  • MCP: Search and read these docs from your assistant with the docs MCP server at https://docs.sparklayer.io/mcp.

This guide takes you from no credentials to a successful API call. You need a SparkLayer account on the Pro or Enterprise plan (opens in a new tab) and a terminal with curl (and jq (opens in a new tab), to read the token from the response).

Use the test environment first

If your account has Test mode set up, create your first key in the test environment and call https://test.app.sparklayer.io. Test and live hold separate data, so you can experiment without affecting your live store.

Create an API key

In the SparkLayer Dashboard, go to Settings,API (opens in your SparkLayer Dashboard in a new tab). For a test key, turn on Test mode in the left-hand menu first.

Select Create new API Key, enter a name such as Quickstart, and copy the three values shown:

ValueUsed as
Site IDThe Site-Id header on every request
Client IDclient_id when you request a token
Client Secretclient_secret when you request a token: shown once

Save your credentials in your shell

So the commands below run as they are, put your values in environment variables. For the test environment, set SPARKLAYER_BASE_URL to https://test.app.sparklayer.io.

Terminal
export SPARKLAYER_BASE_URL="https://app.sparklayer.io"
export SPARKLAYER_SITE_ID="<SITE_ID>"
export SPARKLAYER_CLIENT_ID="<CLIENT_ID>"
export SPARKLAYER_CLIENT_SECRET="<CLIENT_SECRET>"

Request an access token

Exchange the client ID and secret for an access token. The request body is JSON, and the Site-Id header is required here too:

Terminal
curl -s -X POST "$SPARKLAYER_BASE_URL/api/auth/token" \
  -H "Site-Id: $SPARKLAYER_SITE_ID" \
  -H "Content-Type: application/json" \
  -d "{
    \"grant_type\": \"client_credentials\",
    \"client_id\": \"$SPARKLAYER_CLIENT_ID\",
    \"client_secret\": \"$SPARKLAYER_CLIENT_SECRET\"
  }"

The response contains your token, which is valid for one hour (expires_in is in seconds):

Response
{
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "<ACCESS_TOKEN>"
}

To keep the token in a variable for the next step, run the same request through jq:

Terminal
export SPARKLAYER_TOKEN=$(curl -s -X POST "$SPARKLAYER_BASE_URL/api/auth/token" \
  -H "Site-Id: $SPARKLAYER_SITE_ID" \
  -H "Content-Type: application/json" \
  -d "{\"grant_type\":\"client_credentials\",\"client_id\":\"$SPARKLAYER_CLIENT_ID\",\"client_secret\":\"$SPARKLAYER_CLIENT_SECRET\"}" \
  | jq -r .access_token)

Call an endpoint

List your price lists with the Pricing API, sending the token in the Authorization header and your Site ID in the Site-Id header:

Terminal
curl -s "$SPARKLAYER_BASE_URL/api/v2/price-lists?page=1&page_size=100" \
  -H "Site-Id: $SPARKLAYER_SITE_ID" \
  -H "Authorization: Bearer $SPARKLAYER_TOKEN" \
  -H "User-Agent: quickstart/1.0"

You get back a page of price lists, with an empty data list if your site has none yet:

Response
{
  "data": [
    {
      "slug": "base-list",
      "name": "Base Price List",
      "currency_code": "GBP",
      "source": "custom",
      "tax_inclusive_display": false
    }
  ],
  "pagination": {
    "total": 1,
    "per_page": 100,
    "current_page": 1,
    "total_pages": 1
  }
}

The same in code

The same two calls as a script you can build on. It reads the same environment variables.

Node.js 18 or later, with no dependencies:

quickstart.mjs
const { SPARKLAYER_BASE_URL, SPARKLAYER_SITE_ID, SPARKLAYER_CLIENT_ID, SPARKLAYER_CLIENT_SECRET } =
  process.env;

const tokenResponse = await fetch(`${SPARKLAYER_BASE_URL}/api/auth/token`, {
  method: 'POST',
  headers: { 'Site-Id': SPARKLAYER_SITE_ID, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'client_credentials',
    client_id: SPARKLAYER_CLIENT_ID,
    client_secret: SPARKLAYER_CLIENT_SECRET,
  }),
});
if (!tokenResponse.ok) throw new Error(`Token request failed: ${tokenResponse.status}`);
const { access_token } = await tokenResponse.json();

const response = await fetch(`${SPARKLAYER_BASE_URL}/api/v2/price-lists?page=1&page_size=100`, {
  headers: {
    'Site-Id': SPARKLAYER_SITE_ID,
    Authorization: `Bearer ${access_token}`,
    'User-Agent': 'quickstart/1.0',
  },
});
if (!response.ok) throw new Error(`Request failed: ${response.status} ${await response.text()}`);
const { data, pagination } = await response.json();
console.log(`${pagination.total} price lists:`, data.map((list) => list.slug));
Terminal
node quickstart.mjs

For a production integration, reuse the token until it's close to expiry instead of requesting one per call: see Reuse the access token.

If something goes wrong

ResponseWhat to check
400 from /api/auth/tokenThe Site-Id and Content-Type: application/json headers are set, and the body includes all three fields
401 from /api/auth/tokenThe client ID and secret are correct and belong to the environment you're calling: live keys only work with https://app.sparklayer.io, test keys with https://test.app.sparklayer.io
401 or 403 from an API endpointThe Authorization header is Bearer followed by the token, the token is less than an hour old, and you're sending the same Site-Id and base URL you requested the token with
jq: command not foundInstall jq, or copy access_token from the response by hand: export SPARKLAYER_TOKEN="<ACCESS_TOKEN>"

See Errors for the error format and every status code.

Next steps

Every endpoint page in the API reference also has a playground: enter your token and Site ID to try requests from your browser.

Was this page helpful?

Last updated