Skip to content

    Pre-launch API. The concepts described here are settled, but the API shape is not: request and response fields, parameters and defaults can still change. Build against it, and talk to your Luigi's Box contact before you put an integration into production.

    Authentication overview

    View source

    Every call to Luigi’s Box AI carries a short-lived access token in an Authorization header. You never send a long-lived secret to an API endpoint; you exchange a credential for a token first, and the token is narrow — it is valid for one service and one set of resources, and it expires in minutes.

    Which credential you use depends on where the code runs.

    Where your code runsCredentialWhat it can do
    A shopper’s browserA publishable key (pub_…)Read discovery and write analytics events, on one channel — and nothing else
    Your serverAn OAuth client ID and secret (lbk_… / lbe_…)Whatever your integration is granted — indexing, configuration, events, discovery

    Both paths end in the same kind of token, and endpoints do not care which path produced it. They only check what the token is allowed to do.

    A publishable key is visible by design. It ships in your page source, it is bound to the origins you register, and it is bound to exactly one channel. To turn it into a token, the browser solves a proof-of-work challenge that takes a few hundred milliseconds of CPU. The challenge is one layer of bot control, not an authorization mechanism.

    A browser token can do exactly two things.

    It canIt cannot
    Read discovery surfaces — search, collections, recommendations, facets, object lookup, variantsWrite anything to the catalog
    Send analytics eventsRead the catalog configuration
    Touch organizations, catalogs, channels, surfaces or campaigns
    Reach any other channel than the one its key is bound to
    Be used from an origin you have not registered

    Those permissions are derived from the key — the channel it is bound to plus the audience requested — not from your account’s grants. Asking for any other audience produces a token with no permissions.

    See Browser tokens.

    An OAuth client ID and secret exchange for a token with the standard client_credentials grant. The secret never leaves your infrastructure. This is the path for indexing catalog content, configuring feeds, reporting events, and for storefronts that render search server-side.

    Use it for all automation. A server-side script attempting the browser flow is refused by bot control.

    See Server-to-server tokens.

    Luigi’s Box AI runs in independent regions, and a credential belongs to exactly one of them. There are two hosts per region:

    HostPurpose
    https://auth.<region>.luigisbox.aiGetting a token
    https://api.<region>.luigisbox.aiEverything else

    <region> is the zone your account was provisioned in, for example eu1 or us1. Your credentials carry the region in their own value (pub_live_eu1_…), and a credential from one region cannot authenticate in another — if you operate in two regions, you hold two sets of credentials.

    Examples in these docs use eu1. Substitute your own region.

    The API is one host in front of several services, each answering one path prefix. When you request a token you name an audience — the service the token is for. A token minted for indexing cannot be used against discovery.

    ServiceAudience
    Discovery — search, collections, recommendationshttps://api.eu1.luigisbox.ai/discovery
    Content indexinghttps://api.eu1.luigisbox.ai/index
    Catalog configuration — feeds, mappings, metadatahttps://api.eu1.luigisbox.ai/catalog
    Object change historyhttps://api.eu1.luigisbox.ai/ledger
    Analytics events ingestionhttps://api.eu1.luigisbox.ai/events
    Account structure and merchandisinghttps://api.eu1.luigisbox.ai/platform

    Browser tokens accept an array of audiences, so a storefront that both searches and reports behaviour uses one token for both. Server-to-server tokens name a single audience, so a backend that indexes and reports events holds one token per service.

    A 401 on a token that has not expired usually means the token was minted for a different audience.

    Beyond its audience, a token carries the permissions your integration was granted. A permission is always a pair: an action, and the resource it applies to — a specific catalog, a specific channel, a specific surface. “Serve discovery” is not a permission; “serve discovery for channel lbn_4hj9tv” is. An integration granted indexing on one catalog cannot write to another: the grant is not there.

    In practice:

    • Grants are per resource, not per account. Two catalogs in the same organization are two separate grants. Being entitled to one says nothing about the other.
    • You do not assemble them per request. You ask for a token; the permissions your integration holds are stamped into it. There is no scope parameter to widen.
    • You cannot change them yourself. Grants are configured by Luigi’s Box when the integration is set up, and there is no API for an integration to grant itself anything. If a call is refused that should succeed, contact Luigi’s Box.

    Ask for the narrowest set that does the job.

    StatusMeaning
    403The token holds a grant on this resource, but not the one this call needs
    404The token holds no grant on this resource at all

    The API does not confirm that a resource exists to a caller who cannot see it, so a 404 on a single object can mean either. Check the permission before assuming a typo.

    Access tokens are short-lived — about five minutes.

    • Cache the token, not the request. Reuse one token until shortly before it expires, then fetch another. Do not mint one per API call.
    • Retry once on 401. A 401 on a previously working call almost always means the token expired between checks. Get a new one and retry.
    • Never persist a token. It expires before it would be read back.

    Browser tokens work the same way, and re-minting one does not disturb the shopper’s session: the session identifier your integration sends lives independently of the token.