Authentication

How to get your access token, based on OAuth 2.0 grants

We've recently migrated the whole authentication process to our new Authentication API, as detailed in this section. At the moment both the old and new ways of authenticating are supported, but the legacy endpoints, scope syntax, and SSO using a custom org-specific secret key are deprecated and will be dismissed by the end of October 2024. Make sure to update your integration by the specified deadline to avoid any issues.

How to migrate

To migrate to the new authentication process you just need a couple of tweaks to your current codebase:

  1. Change the authentication endpoint from https://yourdomain.commercelayer.io/oauth to https://auth.commercelayer.io/oauth

  2. Stop using the market and/or stock location number (e.g.: market:1234) when including a scope and start using the new syntax with the ID or the code (e.g. market:id:xYZkjABcdeor market:code:europe).

  3. If you using a custom org-specific secret key to sign a manually built JWT for SSO, switch to the JWT bearer flow with a proper assertion.

Check our JS Auth, a TypeScript library wrapper that helps you use Commerce Layer API for authentication, providing also some useful helper methods (e.g. access token decoding).

The new authentication endpoint

All API requests must be authenticated. To get authorized, you must include a valid access token in the Authorization header:

Authorization: Bearer your-access-token

To get a valid access token you need to send a POST request to the following endpoint:

https://auth.commercelayer.io/oauth/token

The payload to be sent with the request differs based on the kind of application you're requesting the access token for and will be detailed case by case in the following sections.

Please note that the authentication endpoint is subject to a rate limit of max 30 reqs / 1 min both in live and test mode.

Authorization grant flows

To get an access token, you need to execute an authorization flow by using valid API credentials for the client.

The authorization flow depends on the grant type as described in the table below:

Grant typeSales channelIntegrationWebapp

Client credentials

Password

Authorization code

Refresh token

JWT bearer

As a general rule, non-confidential (public) applications (e.g. sales channels) can authenticate (requesting and revoking access tokens, using refresh tokens) using just a client ID, without providing a client secret and can be safely used client-side. Confidential (private) applications (e.g. integrations, webapps) need a client secret to authenticate.

Access token expiry

For security reasons, access tokens expire after a default period of time. Your access token lifetime differs based on the kind of application you're using:

API clientDefault lifetime

4 hours

2 hours

2 hours

Refresh tokens have a fixed default lifetime of 2 weeks that cannot be modified.

To avoid security issues, be careful not to set too long expiration dates for your access tokens.

Authorization scopes

For each of the above authorization flows you can restrict the scope to a specific active market and/or stock location.

The access token scope is a string that can be composed in two ways:

  • by ID{{resource_name}}:id:{{resource_id}}

    Where {{resource_name}} can be one of market or stock_location, and {{resource_id}} is the id of the resource (e.g. market:id:xYZkjABcde, stock_location:id:WLgbSXqyoZ).

  • by code{{resource_name}}:code:{{resource_code}}

    Where {{resource_name}} can be one of market or stock_location, and {{resource_code}} is the code of the resource (e.g. market:code:europe, stock_location:code:eu_warehouse).

Defining a market or stock location code and using it for your scope(s) can come in handy to replicate your setup when switching from Test to Live mode which are two different, separate environments where corresponding resources would have different IDs.

Putting a market in scope

By including a market scope in the access token request — market:id:xYZkjABcde — all the resources (e.g. SKUs, prices, stock items) that you fetch are automatically filtered.

{
  "grant_type": "{{authorization_grant}}",
  "client_id": "{{your_client_id}}",
  ...,
  "scope": "market:id:xYZkjABcde"
}

The market in scope must be active (e.g. enabled). Disabled markets are excluded from any authorization scope recalculation.

When fetching a collection of SKUs with a market in scope only the SKUs that are sellable in that market are returned. To be sellable in a market an SKU must have a price in the market's price list and at least one stock item in one of the market's stock locations, regardless of its quantity.

Sales channels require a market in scope when requesting their access tokens to perform the permitted CRUD actions. If the market in scope is associated with a customer group, it becomes private and can be accessed only by the customers belonging to the group — in that case, to get your token you must use the password flow.

Putting a stock location in scope

By including a stock location scope in the access token request — stock_location:id:WLgbSXqyoZ — the stock is restricted to the SKUs available in that specific stock location.

{
  "grant_type": "{{authorization_grant}}",
  "client_id": "{{your_client_id}}",
  ...,
  "scope": "market:id:xYZkjABcde stock_location:id:WLgbSXqyoZ"
}

When putting a stock location in scope, adding the associated market in the access token request is mandatory. If the market scope is missing or the stock location doesn't belong to the market in scope the API responds with a 400 Bad Request error code.

Last updated