Errors
For AI assistants: the facts every SparkLayer API call needs
- Base URLs: Live
https://app.sparklayer.io, testhttps://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/tokenwith aSite-Idheader and a JSON body (not form-encoded):{"grant_type":"client_credentials","client_id":"…","client_secret":"…"}. It returnsaccess_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>andSite-Id: <site id>, plusContent-Type: application/jsonwhen there is a body. Set aUser-Agentthat names your integration. - Errors: RFC 7807 problem details:
title,status,detailand an optionalerrors[]of{ code, message, property }. Some error responses have no body. Retry5xx,429(honouringRetry-After) and concurrent-update409s with exponential backoff; on401, get a new token once and retry; don't retry other4xxwithout changing the request. - Pagination: Most list endpoints return everything.
GET /api/v2/price-listspages withpageandpage_size(up to 250) untilpagination.current_pageequalstotal_pages.GET /api/v1/purchasesuseslimit(up to 500) andoffset: stop when a page has fewer thanlimitresults. - Ground rules: Use only endpoints, fields and SDK methods that the docs or OpenAPI specs define. Prefer
GET /api/v2/price-listsover 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
.mdto 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.
The SparkLayer APIs use standard HTTP status codes: 2xx for success, 4xx when the request needs fixing, and 5xx when something went wrong on SparkLayer's side. Most errors include a JSON body that explains the problem.
Error body
Error bodies follow the RFC 7807 problem details (opens in a new tab) format:
{
"title": "invalid-request-contents",
"status": 400,
"detail": "Unable to validate request contents",
"errors": [
{
"code": "keyword-mismatch",
"message": "<what is wrong with the value>",
"property": "customer_id"
}
]
}| Field | Description |
|---|---|
title | A short identifier for the type of problem, such as invalid-request-contents or resource-not-found |
status | The HTTP status code, repeated for convenience |
detail | A human-readable explanation. Use it for logging and debugging, not to drive your integration's logic |
errors | Optional. A list of individual problems, each with a machine-readable code, a message and, where relevant, the property it applies to |
Some APIs also include "type": "about:blank". Treat the status code as the primary signal, title and errors[].code as more specific detail, and ignore fields you don't recognise.
Differences between APIs
The APIs are separate services, so some responses differ in detail:
- Errors are
application/problem+json, except the cart's Calculate and Complete validation errors (422), which are plainapplication/jsonwith their owncart-errorandcart-validation-errorsshapes. - Invalid price updates sent to the Pricing API (for example with Update prices in a price list) return a
400whose body is a list of{ "line", "field", "message" }objects, so you can match each problem to a row of your JSON array or CSV file. - Some responses, such as a
404for an unknown route, a405, a415or an unexpected500, can have an empty body. - The endpoint pages in the API reference list the responses each operation returns.
Status codes
| Status | Meaning | What to do |
|---|---|---|
200, 201, 204 | Success. 204 responses have no body | — |
207 | Partial success: some items in the request couldn't be processed, and each affected item carries an error. Returned by Get customer-specific pricing | Check each item for an error |
400 | The request is invalid: the body, parameters or headers (including Site-Id) don't match the API's schema, a required value is missing, or the request breaks a business rule | Fix the request using detail and errors. Don't retry it unchanged |
401 | The access token is missing, malformed or expired, or was issued for a different site or environment. On /api/auth/token, the client ID or secret is wrong | Request a new access token, then retry. See Authentication |
403 | The request isn't allowed. The Pricing and Purchasing APIs also return 403 when the Authorization header is missing, or the token was issued for a different site or environment | Check the Authorization and Site-Id headers, and that you're using credentials for the right environment |
404 | The resource or route doesn't exist | Check the ID, slug or lookupBy value and the URL |
405 | The endpoint exists but doesn't support the HTTP method | Check the method in the API reference |
409 | The request conflicts with existing data — for example a duplicate external ID, a newer version of the record already exists, or another update to the same data was running at the same time | Fetch the current state, resolve the conflict and retry |
410 | The resource is gone — for example a file that failed its checks after upload | Don't retry. Upload the file again |
415 | The Content-Type header isn't supported by the endpoint | Send Content-Type: application/json (the Pricing API also accepts text/csv on some endpoints) |
422 | The Ordering API can't process the cart — for example it's empty, or it has validation errors when you try to complete it | See Cart errors |
500 | An unexpected error on SparkLayer's side | Retry with exponential backoff. If it persists, contact support with the request details |
502, 503, 504 | The service is temporarily unavailable or took too long to respond | Retry with exponential backoff |
Authentication errors
Errors from /api/auth/token, and errors caused by a missing or invalid token on the Core and Ordering APIs, use OAuth 2.0 error codes (opens in a new tab) as the title:
{
"title": "invalid_client",
"status": 401,
"detail": "Client authentication failed"
}title | Status | Cause |
|---|---|---|
invalid_client | 401 | The client ID or secret is wrong, the key has been deleted, or it belongs to the other environment |
invalid_request | 400 | A required field, such as client_secret, is missing |
unsupported_grant_type | 400 | grant_type isn't client_credentials |
access_denied | 401 | The Authorization header is missing, or the token is invalid, expired or for another site or environment |
The Pricing, Purchasing, Stock, Sync Logging and Files APIs return a 401 or 403 problem body with a detail explaining why the token was rejected.
Validation errors
When a request doesn't match the API's schema, the response is a 400 with details of each problem in errors. On the Core and Ordering APIs, and for most requests to the Pricing API, the title is invalid-request-contents. The Core and Ordering APIs use these codes:
code | Cause |
|---|---|
keyword-mismatch | A value breaks a schema rule, such as a type, format or length. property points to it |
body-mismatch | The body isn't valid JSON or doesn't match the expected shape |
headers-mismatch | A required header, such as Site-Id or Content-Type, is missing or invalid |
parameters-mismatch | A path or query parameter is invalid, such as an unsupported lookupBy value |
path-mismatch | The path doesn't match the endpoint |
missing-param | A required value is missing |
resource-already-exists | A value that must be unique, such as a slug, is already in use |
resource-id-not-found | An ID or slug in the request doesn't match an existing resource |
resource-id-invalid | An ID isn't in the expected format |
resource-in-use | The resource can't be deleted because something else uses it |
The Purchasing, Stock, Sync Logging and Files APIs describe schema problems in detail instead.
Cart errors
The Ordering API returns 422 when it can't process a cart. The title tells you which kind of problem it is:
cart-error:errorslists codes such ascart-empty,cart-customer-not-found,cart-shipping-rate-handle-unavailableorcart-payment-method-unavailable.cart-validation-errors: returned by Complete a cart when the cart has validation errors you haven't chosen to ignore.errors.validation_error_typeslists them. Fix the cart, or list the types you accept inignore_validation_errors, and try again.
Retrying requests
- Retry
5xxresponses and409conflicts caused by concurrent updates, using exponential backoff. - On a
401, request a new access token once and retry. If it fails again, check your credentials rather than retrying. - Don't retry other
4xxresponses without changing the request. PUTrequests that create or replace a record, such as Create or update a purchase, are safe to repeat. Before retrying aPOSTthat creates something, check whether the first attempt succeeded.
Rate limits
SparkLayer doesn't publish fixed rate limits. Design your integration to be gentle and to recover:
- Send changes in batches using the bulk endpoints (for example Update prices across price lists and Update stock levels for multiple SKUs) rather than one request per SKU.
- Run requests one after another, or with a small number in parallel.
- No SparkLayer API returns
429 Too Many Requeststoday. If you ever receive one, wait before retrying: use theRetry-Afterheader if the response has one, otherwise back off exponentially.
Last updated