docs
  1. SCAYLE Resource Center
  2. Developer Guides
  3. Introduction
  4. APIs

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).

Country ID in SCAYLE Panel.

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.

ParameterDetails
pageThe 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
Default: 100

Response FieldDetails
currentThe 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
totalThe total amount of items which can be retrieved.

Type: Integer
perPageThe perPage parameter which was provided in the request.

Type: Integer
pageThe page parameter which was passed in the request.

Type: Integer
first

The first page which will always be 1.


Type: Integer

prevThe previous page that you can request.
If you are on the first page, the value will be 1.

Type: Integer
nextThe 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.


Type: Integer

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.

ParameterDetails
limitThe limit parameter specifies the maximum number of results to be returned.

Type: Integer
Default: 100
offsetThe 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 FieldDetails
totalThe 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 CodeDescription
200 - OKRequest has been fulfilled.
201 - CreatedRequest has been fulfilled and new resource created.
204 - No ContentThere is no content for a successful request.
206 - Partial ContentRequest has been fulfilled for the partial content requested.
400 - Bad RequestMissing or invalid parameter.
401 - UnauthorizedNo or invalid access token.
404 - Not FoundRequested resource doesn't exist.
408 - Request TimeoutThe client closed the connection.
409 - ConflictRequested resource could not be processed because of a conflict.
412 - Precondition FailedPreconditions were not met.
413 - Payload Too LargeThe request entity is larger than limits defined by server.
424 - Failed DependencyRequest failed due to a failure of dependency.
500 - Internal Server ErrorUnexpected error on Storefront API server.
503 - Service UnavailableService unavailable due to internal errors.

Error Response

ParameterDetails
code

String

HTTP Status Code.

message

String

Description of the error.

details

Array

A list of all error details.

Error Entity

ParameterDetails
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

ParameterDetails
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

ParameterDetails
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

ParameterDetails
entities

Array

An array containing the requested entities.

cursor

Cursor

An object containing information for use in pagination.

Cursor

ParameterDetails
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 NameAdmin API
product_nameWhen 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.
categoryInternally used by SCAYLE to store the leaf category as an attribute.
brandInternally 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-ScopeThe scope to which the endpoint belongs.
X-RateLimit-LimitThe total amount of requests that can be made to the endpoint.
X-RateLimit-RemainingThe remaining amount of requests, which can be made to the endpoint.
X-RateLimit-ResetThe number of seconds until the quota resets.

Rate Limits

ScopeMax attempts / min.
customDataRead2000
customDataWrite1000
customersRead300
customersWrite300
fulfillmentWrite300
globalRead1000
globalWrite300
ordersRead1000
ordersWrite300
pricesRead2500
pricesWrite300
productRead1000
productWrite300
productSortingWrite2500
shopCategoriesRead1000
shopCategoriesWrite300
stocksRead2500
stocksWrite2500
vouchersRead300
vouchersWrite300

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 CodeDescription
200 - OKRequest has been fulfilled.
201 - CreatedRequest has been fulfilled and new resource created.
204 - No ContentRequest has been fulfilled.
400 - Bad RequestMissing or invalid parameter.
401 - UnauthorizedNo or invalid access token.
403 - ForbiddenRequest is not allowed.
404 - Not FoundRequested resource doesn't exist.
409 - ConflictRequested resource could not be processed because of conflict.
412 - Precondition failedRequest didn't met the requirements, it cannot be processed.
413 - Payload too largeThe request payload is too large.
422 - Unprocessable entityRequested resource cannot be processed.
429 - Too many requestsThe request rate limit has been exceeded.
500 - Internal Server ErrorUnexpected error on Admin API server.
502 - Bad gatewayAdmin API server received an invalid response from the upstream server.
503 - Service UnavailableService unavailable due to internal errors.

Error Response

ParameterDetails
errors

Error

A list of all errors occurred.

Error Entity

ParameterDetails
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:

EndpointURL
Update or create product sortingsPOST /product-sortings
Create shipmentPOST /fulfillment/shipments

Check our Admin API Reference Guide for more details.