APIs
Storefront API
The SCAYLE Storefront API is a REST API used to access your product data in any customer-facing application. Use this API to render your shop.
Typical use cases for the Storefront API include:
- Show shop navigation
- Render product listing page and filter
- Show product detail page
- Add products to the basket & wishlist
- Search for products
Check our Storefront Reference Guide for more details.
For end-customers facing critical operations, it's recommended always to use the Storefront API.
Typically, there is no use case when you need to interact with the Admin API from your Storefront.
Authentication
The Storefront API requires the use of API keys for authentication to exclusively access the basket and wishlist endpoints. However, for all other endpoints, authentication is not necessary.
You can maintain your API keys in the SCAYLE Panel.
Authentication to the API is performed via the HTTP Header with your API key as the X-Access-Token
value. You do not need to provide a password.
API requests without authentication for the basket and wishlist endpoints will fail as the endpoints requiring authentication are supposed to be used server-side only.
The backend service is responsible for authenticating and authorizing users. For example, the service only allows users to access their own data.
Your API Tokens grant many privileges, so it is important to use and store them in a secure way. Do not use your token in client-side code or any publicly accessible areas like Git repositories.
Country Identification
To access data through the Storefront API, you generally specify the shop-country ID (as opposed to the global shop ID), since all data is associated with a specific shop country.
Ensure accurate and relevant data retrieval by incorporating the country ID into your API requests.
The country ID is required on all endpoints and needs to be provided as the shopId
query parameter, for example /v1/products?shopId=1001
.
You can find the country ID in the SCAYLE Panel on the Dashboard page of your shop. Ensure the shop country is selected in the dropdown menu (see image below).
SDK Setup
SCAYLE's Storefront API SDKs simplify use of the Storefront REST APIs by, for instance, reducing the amount of boilerplate code you have to write. Below are installation instructions for the SDK libraries in a variety of popular server-side programming languages.
Installation
npm i @scayle/storefront-api
For other languages we provide an OpenAPI Spec which can be used to generate the SDK for any language supported by the OpenAPI SDK Generator.
For a full list of available generators and their options, see the OpenAPI Docs.
If you already have Docker installed, the easiest option is to use the provided Docker Image from OpenAPI:
Here we run the OpenAPI Generator CLI through the Docker Image and generate the PHP SDK.
We mount the current working directory into the Docker Image and write the generated SDK into the generated/storefront-api/php
folder.
The OpenAPI Spec is taken directly from the Storefront API that is currently deployed on your tenant space.
To update the SDK with the latest version later, you can just run the same command again.
docker run
--rm
-v "${PWD}:/local"
openapitools/openapi-generator-cli
generate
-i https://{{tenant-space}}.storefront.api.scayle.cloud/docs/swagger.yaml
-g php
-o /local/generated/storefront-api/php
Initialize SDK / Client
The following code snippets show how to initialize the Storefront API SDK / client for specific languages by using the minimal required configuration options.
import { StorefrontAPIClient } from '@scayle/storefront-api'
const client = new StorefrontAPIClient({
host: '{{tenant-space}}.storefront.api.scayle.cloud',
shopId: 1001,
auth: {
type: 'token',
token: '{{Access-Token}}',
},
});
Test Connection
To test your connection, attempt a query to retrieve information about all the products in your shop.
const response = await client.products.query({});
console.log(response);
If you have a new instance and no shops with products have been created, the above query would result in an empty response.
Pagination
Pagination is essential for working with larger data sets where it is not feasible to fetch all data in a single call.
All top-level API resources which return a list of items always returns pagination information as well in the response.
Whether pagination on the request is also supported can be found on each endpoint.
If you go over the available items with your pagination, the APIs will return empty responses.
The Storefront API offers to ways to perform pagination:
Page-based Pagination
The page-based pagination is used by default if you won't specify otherwise in the request for all endpoints.
Parameter | Details |
---|---|
page | The page you want to retrieve items for. Type: Integer Default: 1 |
perPage | How many items you want to retrieve per page. This parameter should stay the same between requests to avoid duplicate or missing items. Type: Integer |
Response Field | Details |
---|---|
current | The current amount of items returned to you. In most cases this will be equal to the perPage parameter unless we don't have more items to be returned. For example, if you request the last page and we only have 10 products left to be returned, then the value will be 10. Type: Integer |
total | The total amount of items which can be retrieved. Type: Integer |
perPage | The perPage parameter which was provided in the request. Type: Integer |
page | The page parameter which was passed in the request. Type: Integer |
first | The first page which will always be 1.
|
prev | The previous page that you can request. If you are on the first page, the value will be 1. Type: Integer |
next | The next page to be requested. If you are on the last page, this will be the same value as the 'page' response field. Type: Integer |
last | The last page that you can request.
|
Offset-based Pagination
Offset-based pagination allows you to be more flexible with your requests as the amount of items you retrieve per call can be varied.
The offset parameter just needs to match how many items you previously retrieved and then you can change the limit parameter while iterating through your data.
Parameter | Details |
---|---|
limit | The limit parameter specifies the maximum number of results to be returned. Type: Integer Default: 100 |
offset | The offset parameter defines from which item position we should return items. This should be the total number of items you previously retrieved. Example: When requesting all of your products in chunks of 50, on every iteration you should increment your offset by 50 until you reach the end. Type: Integer Default: 0 |
Response Field | Details |
---|---|
total | The total number of items for this resource. Once your offset parameter is bigger than the total amount of items, you have reached the end of your data. Type: Integer |
Versioning
A new version of a specific endpoint is released when backwards-incompatible changes are applied. Backwards-compatible changes do not create a new version.
The Storefront API uses URI versioning where the first path segment is the version requested for the endpoint.
We generally try to keep backwards compatibility, however in certain situations it is not possible for us to do so.
Backwards-Compatible Changes
When backwards-compatible changes are made to the Storefront API, no new version is released. Backwards-compatible changes include the following:
- Adding new API resources.
- Adding new optional request parameters.
- Adding new properties to responses.
Backwards-Incompatible Changes
When backwards-incompatible changes are made to the Storefront API, a new version is released. Backwards-incompatible changes include the following:
- Deleting existing API resources.
- Adding new required parameters to existing API methods.
- Removing properties from an existing API response.
- Changing data types of existing properties.
Errors
The Storefront API uses HTTP status codes to indicate the success or failure of an API request. In general the 2xx
range indicates success, the 4xx
range indicates a failure caused by the provided information, and the 5xx
range indicates a problem with Storefront API servers.
If an error occurs, the Storefront API responds with an error response containing a list of errors. In most cases, the list will contain a single error. However, some endpoints might return multiple errors.
The status codes, error responses, and error entities are provided in the tables below.
HTTP Status Codes
HTTP Status Code | Description |
---|---|
200 - OK | Request has been fulfilled. |
201 - Created | Request has been fulfilled and new resource created. |
204 - No Content | There is no content for a successful request. |
206 - Partial Content | Request has been fulfilled for the partial content requested. |
400 - Bad Request | Missing or invalid parameter. |
401 - Unauthorized | No or invalid access token. |
404 - Not Found | Requested resource doesn't exist. |
408 - Request Timeout | The client closed the connection. |
409 - Conflict | Requested resource could not be processed because of a conflict. |
412 - Precondition Failed | Preconditions were not met. |
413 - Payload Too Large | The request entity is larger than limits defined by server. |
424 - Failed Dependency | Request failed due to a failure of dependency. |
500 - Internal Server Error | Unexpected error on Storefront API server. |
503 - Service Unavailable | Service unavailable due to internal errors. |
Error Response
Parameter | Details |
---|---|
code | String HTTP Status Code. |
message | String Description of the error. |
details | Array A list of all error details. |
Error Entity
Parameter | Details |
---|---|
field | String Describe field where the error occurred. |
description | String Some human-readable description of the error. |
Admin API
The Admin API is a JSON REST API that provides access to your data. Typical use-cases for the Admin API are:
- Manage product data such as categories, variants, images, prices, and price campaigns.
- Handle inventory and warehouses.
- Manage translations and localization for different shops.
- Create and administer different shops.
SDK Setup
SCAYLE's Admin API SDKs simplify use of the Admin REST API by, for instance, reducing the amount of boilerplate code you have to write. Below are installation instructions for the SDK libraries in a variety of popular server-side programming languages.
Installation
Install the library via your dependency management tool:
# Install with npm
npm install swagger-client
# Install with yarn
yarn add swagger-client
Manual Installation
Alternatively, you can grab the latest stable release for PHP SDK or Java SDK and copy it into your project's folder, so you can share it with your team without a private registry.
Initialize SDK / Client
The following code examples show how to initialize the Admin API SDK/client for specific languages using the minimal required configuration options.
# Install with npm
npm install swagger-client
# Install with yarn
yarn add swagger-client
// Some code
Timeout Settings
The SDK's HTTP clients come with no default timeout setting, meaning requests will not be terminated until a response is received from the backend.
However, if a client side timeout is deemed necessary, it is recommended to set it at a minimum of 380
seconds.
Authentication
The Admin API uses API keys to authenticate requests. You can maintain your API keys in the SCAYLE Panel.
Authentication to the API is performed via the HTTP Header with your API key as the X-Access-Token
value. You do not need to provide a password.
Access your Admin API by calling https://{{tenant-space}}.admin.api.scayle.cloud/api/admin/v1
.
If your Tenant is "acme" and the space is "live" the Admin API URL is:
https://acme-live.admin.api.scayle.cloud/api/admin/v1
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.
Your API Tokens grant many privileges, so it is important to use and store them in a secure way. Do not use your token in client-side code or any publicly accessible areas like Git repositories.
Authenticated Request
import SwaggerClient from "swagger-client";
const adminApi = await new SwaggerClient({
url: `${process.env.ADMIN_API_URL}admin-api.json`,
authorizations: {
accessToken: {
value: process.env.ADMIN_API_TOKEN
}
}
});
Test Connection
To test your connection, attempt a query to retrieve information about all the shops in your system. In the case of a new system, it is possible that no shops have been created yet, resulting in an empty response.
const response = await adminApi.apis.Shops.getShops();
const shops = response.body.entities;
console.log(shops.length);
Nested Resources
Many resources allow you to request additional information as a nested resource by using the with
request parameter. This parameter is available on all Admin API requests and applies the requested additional resources to the response.
By default, an Admin API response will only contain the requested resource. If you want to include additional resources in the response, you have to explicitly define their names in the with
parameter.
The 'With' Parameter
Parameter | Details |
---|---|
with | String Comma separated list of resource names to include. |
Basic Usage
You can include resources by specifying them as comma separated lists. For example, setting the with
parameter to images,variants
on a product will include all images and variants in the response.
Recursive Usage
You can include nested resources recursively by specifying nested fields after a dot. For example, setting the with parameter to images,variants.attributes
on a product will include all images and variants with their attributes in the response.
Get Products with Images, Variants, and Variant Attributes
let response = await client.apis.Products.getProducts({with: "images,variants.attributes"});
let products = response.body.entities;
products.forEach(
product => product.images.forEach(
image => console.log(image.assetUrl)
)
);
Identifiers
The Admin API allows you to request resources by using two types of identifiers:
id
referenceKey
When referring to a resource outside the SCAYLE ecosystem, you often have to provide a referenceKey
as a unique identifier for the resource. However, if the resource was created by SCAYLE, it is assigned an internally unique identifier called id
. You can choose between these two types of identifiers to request a resource.
The ID is an ecosystem-exclusive identifier. However, once you set a reference key, you can also refer to it internally.
Using the ID
let response = await client.apis.Products.getProduct({productIdentifier: 123});
let product = response.body;
Using the Reference Key
let response = await client.apis.Products.getProduct({productIdentifier: "key=my-key-123"});
let product = response.body;
Pagination
Most of the API resources have support for bulk retrieval. For instance, you can get a collection of products, variants, or attribute groups. These API methods share a common structure, supporting at least these two parameters: limit and cursor.
Parameters
Parameter | Details |
---|---|
limit | Integer A limit on the number of entities to be returned. Each API resource can have a different default value. |
cursor | String A valid cursor for use in pagination. Can be retrieved from the collection response. |
Collection Response Format
Parameter | Details |
---|---|
entities | Array An array containing the requested entities. |
cursor | Cursor An object containing information for use in pagination. |
Cursor
Parameter | Details |
---|---|
next | String READ-ONLY The cursor pointing to the next page. If null there is no next page available. |
Example: Iterate over an Attribute Group Collection
let options = {
limit: 5
};
let collection = null;
do {
let response = await client.apis.AttributeGroups.getAttributeGroups(options);
collection = response.body;
collection.entities.forEach(
attributeGroup => console.log(attributeGroup.name)
);
options.cursor = collection.cursor.next;
} while (collection.cursor.next !== null);
Standard Attributes
The Admin API internally uses predefined standard/reserved attribute group names for some use cases. The table below lists all of these attribute groups including a mapping of how these are populated via Admin API.
- You can not manually create a reserved attribute group.
- The Storefront API has pre-embedded support for returning the respective attributes.
Reserved Attribute Groups
Attribute Group Name | Admin API |
---|---|
product_name | When working with the products, you have to specify a translatable product name via the name property. Internally, this is saved to an attribute of the group product_name . |
category | Internally used by SCAYLE to store the leaf category as an attribute. |
brand | Internally used by SCAYLE to store the brand as an attribute. |
Versioning
A new version is released when backwards-incompatible changes are applied. Backwards-compatible changes will not create a new version.
The Admin API uses URI versioning. For example, https://{{tenant-space}}.admin.api.scayle.cloud/api/admin/v1
. The current version is v1. Whenever making a request to the Admin API, you have to specify the version inside the URI.
Backwards-Compatible Changes
When backwards-compatible changes are made to the Admin API, no new version is released. Backwards-compatible changes are defined as:
- Adding new API resources.
- Adding new optional request parameters.
- Adding new properties to responses.
Backwards-Incompatible Changes
When backwards-incompatible changes are made to the Admin API, a new version is released. Backwards-incompatible changes are defined as:
- Deleting existing API resources.
- Adding new required parameters to existing API methods.
- Removing properties from an existing API response.
- Changing data types of existing properties.
Rate Limit
Rate limits control the number of requests per unit time.
The Admin API limits the number of calls to its endpoints to keep the system load under the manageable level.
Rate Limit Scopes
Most Admin API endpoints belong to a rate limit scope such as stockWrite, productRead, etc. Each scope defines its own rate limit, meaning that there might be no more than X requests within Y minutes to an endpoint of the particular scope.
It is important to note that every rate limit scope is isolated. Moreover, there are usually dedicated scopes for read and write operations. For example, if you have reached the limit by adding new stocks in the system, you can still retrieve stocks for a specific variant.
You can find the actual scope limits and the relation between an endpoint and a scope in the API Reference. If it is not mentioned to which scope an endpoint belongs, it means the amount of requests is not limited. Also note that these rate limits are the default values, which might vary from tenant to tenant.
Rate Limit Header
Every API response includes the following rate limit related headers:
Header Parameter | |
---|---|
X-RateLimit-Scope | The scope to which the endpoint belongs. |
X-RateLimit-Limit | The total amount of requests that can be made to the endpoint. |
X-RateLimit-Remaining | The remaining amount of requests, which can be made to the endpoint. |
X-RateLimit-Reset | The number of seconds until the quota resets. |
Rate Limits
Scope | Max attempts / min. |
---|---|
customDataRead | 2000 |
customDataWrite | 1000 |
customersRead | 300 |
customersWrite | 300 |
fulfillmentWrite | 300 |
globalRead | 1000 |
globalWrite | 300 |
ordersRead | 1000 |
ordersWrite | 300 |
pricesRead | 2500 |
pricesWrite | 300 |
productRead | 1000 |
productWrite | 300 |
productSortingWrite | 2500 |
shopCategoriesRead | 1000 |
shopCategoriesWrite | 300 |
stocksRead | 2500 |
stocksWrite | 2500 |
vouchersRead | 300 |
vouchersWrite | 300 |
If you need a higher rate-limit please contact your Customer Success Manager.
Rate Limit Response Example
{
"errors": [
{
"errorKey": "RATE_LIMIT_EXCEED",
"message": "The request rate limit exceeded. Please try again later.",
"context": {}
}
]
}
Errors
The Admin API uses HTTP status codes to indicate the success or failure of an API request. In general the 2xx
range indicates success, the 4xx
range indicates a failure caused by the provided information, and the 5xx
range indicates a problem with Admin API servers.
If an error occurs, the Admin API responds with an error response containing a list of errors. In most cases, the list will contain a single error. However, some endpoints might return multiple errors.
HTTP Status Codes
HTTP Status Code | Description |
---|---|
200 - OK | Request has been fulfilled. |
201 - Created | Request has been fulfilled and new resource created. |
204 - No Content | Request has been fulfilled. |
400 - Bad Request | Missing or invalid parameter. |
401 - Unauthorized | No or invalid access token. |
403 - Forbidden | Request is not allowed. |
404 - Not Found | Requested resource doesn't exist. |
409 - Conflict | Requested resource could not be processed because of conflict. |
412 - Precondition failed | Request didn't met the requirements, it cannot be processed. |
413 - Payload too large | The request payload is too large. |
422 - Unprocessable entity | Requested resource cannot be processed. |
429 - Too many requests | The request rate limit has been exceeded. |
500 - Internal Server Error | Unexpected error on Admin API server. |
502 - Bad gateway | Admin API server received an invalid response from the upstream server. |
503 - Service Unavailable | Service unavailable due to internal errors. |
Error Response
Parameter | Details |
---|---|
errors | Error A list of all errors occurred. |
Error Entity
Parameter | Details |
---|---|
errorKey | String A key that describes the occurred error. |
message | String Some human-readable description of the error. |
context | Array Additional context to interpret the error message. |
Error Handling
new SwaggerClient(config)
.then(
async client => {
try {
let response = await client.apis.Products.getProducts();
} catch (e) {
console.log(e.response.body);
}
}
);
Limitations
Multiple shop countries with the same country code
There are limitations for the endpoints bound to a shop country. To support a shop country with different languages, we need to create multiple entries for the same country code, each representing a different language. For example, to create a shop country for Switzerland with three different languages—German, French, and Italian—you would set up three separate entries, each with the country code for Switzerland but differentiated by the language attribute.
In such a case, when having multiple shop countries with the same country code, to avoid errors, we recommend using the shop country ID, instead of shop country code, when performing GET / POST / PUT / DELETE requests that are bound to shop country (endpoint URLs having the /shops/{shopKey}/countries/{countryCode}
namespace).
If you tried to get a shop country by country code, the GET /shops/{shopKey}/countries/{countryCode}
would respond with:
- errorKey: SHOP_COUNTRY_IS_AMBIGUOUS
- message: Shop country can not be identified due to duplicates
To overcome this issue, you would need to send the shop country ID as countryCode
.
The same applies for POST/PUT/DELETE endpoints as well, when trying to create/update/delete a resource bound to a shop country, you need to use the shop country id as countryCode
, otherwise the same SHOP_COUNTRY_IS_AMBIGUOUS
error would be returned.
Please find bellow the list of endpoints that have the countryCode
part as the payload:
Endpoint | URL |
---|---|
Update or create product sortings | POST /product-sortings |
Create shipment | POST /fulfillment/shipments |
Check our Admin API Reference Guide for more details.