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.
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 runs | Credential | What it can do |
|---|---|---|
| A shopper’s browser | A publishable key (pub_…) | Read discovery and write analytics events, on one channel — and nothing else |
| Your server | An 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.
The two flows
Section titled “The two flows”From the browser
Section titled “From the browser”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 can | It cannot |
|---|---|
| Read discovery surfaces — search, collections, recommendations, facets, object lookup, variants | Write anything to the catalog |
| Send analytics events | Read 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.
From your server
Section titled “From your server”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.
Hosts and regions
Section titled “Hosts and regions”Luigi’s Box AI runs in independent regions, and a credential belongs to exactly one of them. There are two hosts per region:
| Host | Purpose |
|---|---|
https://auth.<region>.luigisbox.ai | Getting a token |
https://api.<region>.luigisbox.ai | Everything 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.
Audience: which service a token is for
Section titled “Audience: which service a token is for”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.
| Service | Audience |
|---|---|
| Discovery — search, collections, recommendations | https://api.eu1.luigisbox.ai/discovery |
| Content indexing | https://api.eu1.luigisbox.ai/index |
| Catalog configuration — feeds, mappings, metadata | https://api.eu1.luigisbox.ai/catalog |
| Object change history | https://api.eu1.luigisbox.ai/ledger |
| Analytics events ingestion | https://api.eu1.luigisbox.ai/events |
| Account structure and merchandising | https://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.
Permissions
Section titled “Permissions”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.
When a call is refused
Section titled “When a call is refused”| Status | Meaning |
|---|---|
403 | The token holds a grant on this resource, but not the one this call needs |
404 | The 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.
Token lifetime
Section titled “Token lifetime”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. A401on 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.
See also
Section titled “See also”- Browser tokens — publishable keys and the proof-of-work flow
- Server-to-server tokens — the client credentials flow
- Browser quickstart — a working search box
- Backend quickstart — a working indexing call
Was this page helpful?
Thanks.