Morffeus Docs
morffeus.com

Authentication

Every call to the Integration API carries a token in the Authorization header. A token belongs to a user of your app and works for the whole app: it reads and writes that app's data and nothing else.

Get a token#

In Admin, open User › Tokens and create a token for the system that will use it. Use a separate token for every system that talks to us, your ERP, your warehouse, your POS, so you can revoke one without touching the others.

A token is a key to your app's data. Keep it on your server, in an environment variable or a secrets store. Never put it in a browser, a mobile app or a repository. Apps and sites your customers use call the Storefront API with a session of their own instead.

Send it with every request#

Put the token in the Authorization header after the word Bearer:

  • Write Bearer exactly like that, followed by one space and the token.
  • Send one Authorization header. A request with two is treated as having none.
  • The token goes in the header only, never in the URL or the body.

Basic authentication with app keys is not accepted on the Integration API. In the public API it only starts a storefront session.

GET/warehouses
curl "https://api.morffeus.com/api/v2/warehouses" \
  -H "Authorization: Bearer $MORFFEUS_TOKEN"
const res = await fetch('https://api.morffeus.com/api/v2/warehouses', {
  headers: { Authorization: `Bearer ${process.env.MORFFEUS_TOKEN}` }
});
$ch = curl_init('https://api.morffeus.com/api/v2/warehouses');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Bearer ' . getenv('MORFFEUS_TOKEN'),
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
Error401 Unauthorized
{
  "errors": {
    "token": "API.Token.NotFound"
  }
}

What a token carries#

A token is made for one user of one app. You never send an app id: everything below comes from the token.

PartWhat it decides
appWhose data you read and write. Every call works inside this app.
clientThe company the app belongs to.
userWhose rights apply where an endpoint checks them. GET /orders, for example, returns only orders from the sales channels this user may see.
market, currencyThe prices and currency in responses, for example on GET /products.
languageThe language of translated texts in responses, such as unit names on GET /stocks.

Expiry and revocation#

Tokens expire. How long a token lives is set for your app; once it has expired, calls fail with 401 and expired, and you create a new one in User › Tokens.

Revoking a token in User › Tokens stops it at once. We look every token up on every call, so a revoked token fails with API.Token.NotFound from the next request on.

When a token is refused#

A refused token gets 401 and a body that names the token field. The value tells you why:

errors.tokenWhy
API.Authorization.ErrorNo Authorization header, or more than one.
Invalid authorization formatThe header is not Bearer, one space and the token.
invalid, API.Token.InvalidThe token is not one of ours, or it was cut or changed on the way.
expiredThe token's lifetime is over. Create a new one.
API.Token.NotFoundThe token was revoked.
API.Autorization.UnauthorizedThe token is valid but not accepted here, for example Basic authentication or a guest storefront session. The key is spelled this way in the API.

Every other error has the same envelope with a different field. See Errors.

Storefront calls#

The Storefront API does not use these tokens. An app or site your customers use starts a session with the app's keys and signs the customer in; every call then carries that session's token in the same Authorization: Bearer header. See Sessions & sign-in.

Last updated 30 September 2026 · API v2 Something wrong on this page?