Custom APIs (Beta)

While B2C commerce provides powerful tools to customize shopper experiences, we lacked such capabilities for our REST-based API for a long time. With SCAPI today customization is possible via Hooks, where developers can add filters or modify a response before it gets sent back to the calling application.

To leverage even further the power of our B2C Commerce Script API, we now provide a framework where developers can write custom script code, such as controllers, and expose this functionality as a REST API under the SCAPI framework.

A Custom API URL has the following structural format:

https://{shortCode}.api.commercecloud.salesforce.com/custom/{apiName}/{apiVersion}/organizations/{organizationId}/{endpoint}

The term custom must be used for the API family. The parameters API name, API version, and endpoint can be defined as described in the following documentation.

In order to create a Custom API, three components are required:

  • The API contract as an OAS 3.0 schema file.
  • The API implementation as a script using the B2C Commerce Script API.
  • The API mapping is defined in an api.json file.

Custom APIs are defined within custom code cartridges. In the cartridge directory, a new folder rest-apis must be created which is the root folder for all APIs in that cartridge.

In the rest-apis folder, subdirectories represent the actual APIs. The names of these directories represent the API names as they are addressed by the URL. Each directory contains the files for the three components representing this API.

Example: The structure for an API called loyalty-info is expected to look like this:

API directory names can only consist of alphanumeric lowercase characters and a hyphen.

Due to the registration process, it is recommended to start implementing Custom API endpoints in a new code version.

The API contract must be provided by an OAS 3.0 schema file in YAML format. For more information about OAS 3.0, refer to the OAS 3.0 specification.

In this schema file, the API version and the endpoints are defined. The API version is located in the info.version field and is transformed into a URL version by using the major version segment and prepending it with v (for example, 1.0.1v1).

The endpoints are defined as part of the paths object and can implement multiple operations (such as HTTP methods). Each operation is required to have a property called operationId, which must be unique within the schema file. It is used for mapping the endpoint to the implementation.

In order to secure the endpoint, a valid security scheme must be defined, both as a component and for the endpoint. See Authentication for more details.

Example: The schema for a /customers/{id} endpoint in version v1 is expected to look like this:

schema.yaml:

The API implementation is provided by a script file using the B2C Commerce Script API. The function name must match the value of the endpoint’s operationId in the contract.

Example: A valid implementation for /customers/{id} based on the definition in the contract could look like this:

script.js:

It is strongly recommended to always return responses in JSON format. Errors should additionally abide by the SCAPI error format as described in RFC 7807, with at least the type field being present. Response bodies are subject to validation in the future and could be declined if they don’t meet these requirements.

The API mapping is provided by an api.json file. It contains a list of endpoints, and for each entry the endpoint name, its schema file, and the name of the implementing script is defined.

Example: A valid mapping for /customers/{id} based on the definitions in the contract and implementation is expected to look like this:

api.json:

Relative paths are not supported. The schema and implementation must be located at the same level as the corresponding api.json.

The implementation name must be provided without the file extension.

When the Custom API endpoints have been correctly defined as described earlier, they must be registered in order to be accessible.

Before this can be done, enable the feature by navigating to the Feature Switches screen and enabling the feature switch SCAPI Custom API (Beta).

Afterwards, the registration is triggered by activating the code version containing the new API definitions. Whenever changes to an API are required, it is recommended to work in a new code version and to switch the version when ready.

Custom API versions are represented in two different formats, the API version and the URL version.

The API version is defined in the contract as part of the info.version field and applies to all endpoints defined in this file. The value must be numeric but can have multiple segments separated by a dot.

In the URL, the version is transformed by using the major version segment and prepending it with v . For example, this list shows valid API versions and their corresponding URL versions:

  • 1 → v1
  • 1.0 → v1
  • 2.0 → v2
  • 2.0.1 → v2

It is recommended to introduce breaking changes in a new major version. Please see the SCAPI Change Policy for details.

Currently, the only supported authentication mechanism is Shopper Login (SLAS). Securing the API access at first requires defining the scheme with the name ShopperToken in the components section. The purpose of this section is to define reusable elements:

Afterwards, it must be added to the endpoints. This can be done globally or at each operation.

Example 1: Defining the security scheme globally (that is, for each endpoint defined in the schema)

Example 2: Defining the security scheme at an operation

Not using ShopperToken , or using no security at all, prevents the endpoints from being registered.

When the endpoints have been correctly secured in the contract, make sure to retrieve and send a valid SLAS token with each request to your Custom API.

All request parameters must be defined in the contract as requests with unknown parameters are declined. Custom query parameters must be prefixed with c_. Specific system query parameters should also be added to the contract if used.

Example: Defining a mandatory query parameter with the name c_status and the type integer. If the parameter is not present or is not a valid integer, the request is declined.

The following system query parameters exist and can be used when defined in the contract:

  • siteId - The current site of the request. Falls back to the Business Manager site if not present.
  • locale - The current locale of the request. Falls back to the site’s default locale if not present.

Please note that using a shopper token in a Business Manager site context is not allowed. Due to the fallback mechanism, the siteId parameter must always be set when authenticating with ShopperToken.

Example 1: Defining the system query parameter with the name siteId and the type string. If the parameter is not a valid string, the request is declined.

Example 2: Defining the system query parameter with the name locale and the type string. If the parameter is not a valid string, the request is declined.

Example 3: Making a Custom API request with system query parameters:

Relying on the fallback mechanism is not recommended as it can lead to unexpected behavior. Please always add the system query parameters to the API contract and set them accordingly.

The following limitations are in place:

  • Maximum request runtime of 10 seconds.
  • Transactions can’t be committed in the case of GET requests.
  • For the Beta phase, only HTTP GET requests are supported.

When a Custom API endpoint is not accessible as expected, the following checklist can help to find the root cause. This checklist is meant to verify the structure of the cartridge (for example,. the folder structure) and the included required files. It doesn’t check the implementation itself.

  1. Does the cartridge that includes the Custom API components have the correct structure?
    1. Is the rest-apis folder included?
    2. Does the rest-apis folder contain at least one subfolder?
    3. Does the subfolder name of rest-apis consist of only alphanumeric lowercase characters or hyphens?
    4. Does the subfolder of rest-apis contain the mapping file and at least one schema file and implementation script?
  2. Is the cartridge that includes the Custom API components uploaded to the correct SFCC instance?
  3. Is the code version to which the Custom API components were uploaded the active code version?
    1. Each code version activation registers the Custom API endpoints.
  4. Is the cartridge that includes the Custom API components assigned to the correct site?
  5. Is the version used in the request correct?
    1. Is the corresponding API version defined in the schema file?
    2. Does the API version match? API version and URL version have different formats (for example, API version 1.0.1 → URL version v1)
  6. Is the schema file correct?
    1. Is the structure of this file correct?
    2. Is a version given?
    3. Is the securitySchemes part given?
    4. Is at least one endpoint given, including the attribute operationId?
    5. Is the security part given, either globally or per endpoint?
    6. Is ShopperToken used as a security scheme?
  7. Is the implementation script correct?
    1. Are the respective endpoints exported in this implementation script? → see mapping file and schema file (attribute operationId) which endpoints should be exported by this script file.
    2. Does the endpoint return a response in JSON format?
  8. Is the mapping file correct?
    1. Is the structure of this file correct?
    2. Are no file extensions included in the name of the implementation scripts?
    3. Are the used schema files and implementation scripts on the same level as the mapping file?
    4. Do the used schema files exist?
    5. Do the used implementation scripts exist?
    6. Are the given endpoints referenced in the related schema file and the implementation script?
    7. Does the value of the endpoint property match the function name in the script and the operationId in the schema?
  9. Does an implementation script and a schema file exist for this version?
  10. Does the mapping file include the correct implementation script and the correct schema file?
  11. Are all path parameters (system parameter and custom parameter) defined in the schema file?
    1. Are the system parameters siteId and locale defined in the schema file?
    2. Do custom parameters start with c_?
    3. Do all parameters have a defined type?
    4. Does the definition of all parameters match the expected structure of parameter definitions?
  12. Does the request have a valid SLAS token?