Skip to content

API Principles

View MD

Luigi’s Box provides HTTP-based APIs for two main purposes: serving search results to users (Public) and managing your data/configuration (Private).

Auth: Requires only your public tracker_id.

Usage: Safe to call from Frontend (Browsers, Mobile Apps).

CategoryMethodBase URLEndpointDescription
SearchGET/POSTlive.luigisbox.com/searchFull-text search & facets.
AutocompleteGETlive.luigisbox.com/autocomplete/v2Prefix-based suggestions.
RecommenderPOSTlive.luigisbox.com/v1/recommendProduct recommendations.
Shopping AssistantPOSTlive.luigisbox.com/v1/assistantAI-powered structured dialogue that helps customers discover products.
Top itemsGETlive.luigisbox.com/v1/top_itemsMost popular items.
Trending queriesGETlive.luigisbox.com/v2/trending_queriesTrending search terms.
AnalyticsPOSTapi.luigisbox.com/v1Events API. Ingest user interactions.

Auth: Requires HMAC Signature using your Private Key. Usage: Backend Server ONLY.

Manage your product catalog.

MethodBase URLEndpointDescription
POSTlive.luigisbox.com/v1/contentCreate/Replace. Add new products.
PATCHlive.luigisbox.com/v1/contentPartial Update. Update specific fields.
DELETElive.luigisbox.com/v1/contentDelete. Remove products.
PATCHlive.luigisbox.com/v1/update_by_queryBatch Update. Update items matching a query.
GETlive.luigisbox.com/v1/content_exportExport. Download your current index data.

Manage pinning rules and batch recommendations.

MethodBase URLEndpointDescription
POSTlive.luigisbox.com/v1/recommender/pin/{ID}/scopesDefine pinning scopes (rules).
GETlive.luigisbox.com/v1/recommender/pin/{ID}/summaryGet pinning configuration summary.
POSTlive.luigisbox.com/v1/recommender/batching/{ID}/usersTrigger batch recommendation generation for users.
*live.luigisbox.com/v1/recommender/pin/*Various CRUD endpoints for managing pins.

Only the Private API endpoints require a custom HMAC-SHA256 signature.

You will need your API credentials found in Luigi’s Box App > Settings > Integration Settings:

  • Tracker_ID (Public Key): Identifies your account.
  • Secret Key (Private Key): Used to sign requests.

To authenticate, you must construct a specific “String to Sign,” hash it, and attach it as a header.

flowchart TD
A["HTTP method"]
B["Content-Type"]
C["Date header"]
D["Path"]
E["Canonical string"]
F{"Hash function"}
G["Raw bytes"]
H["Final signature"]
I["Authorization header"]
J["API server"]
Key["Private secret"]
A --> E
B --> E
C --> E
D --> E
E -->|HMAC SHA-256| F
Key -.-> F
F -->|Binary output| G
G -->|Base64 encode| H
H -->|Format string| I
I -->|Send| J

Every authenticated request must include these headers. The values used here must match the values used in the signature generation byte-for-byte.

HeaderDescription
DateThe current timestamp in HTTP Date format (e.g., Thu, 29 Jun 2017 12:11:16 GMT). Note: Our server clock tolerance is ±5 seconds. You must regenerate the date and signature for every request.
Content-TypeDescribes your payload (e.g., application/json; charset=utf-8).
AuthorizationThe authentication string. Format: AppName [tracker_id]:[signature]

Concatenate the following four strings, separated by a newline character (\n).

  1. HTTP Verb: Uppercase (e.g., POST, PUT, DELETE).
  2. Content-Type: Exactly as sent in the header (e.g., application/json; charset=utf-8).
  3. Date: Exactly as sent in the header.
  4. Resource Path: The absolute path excluding the query string (e.g., /v1/content, not /v1/content?foo=bar).
  1. Compute the HMAC-SHA256 digest of the Canonical String using your Secret Key.
  2. Encode the binary digest into a Base64 string.
require 'time'
require 'openssl'
require 'base64'
def digest(key, method, endpoint, date)
content_type = 'application/json; charset=utf-8'
data = "#{method}\n#{content_type}\n#{date}\n#{endpoint}"
dg = OpenSSL::Digest.new('sha256')
Base64.strict_encode64(OpenSSL::HMAC.digest(dg, key, data)).strip
end
date = Time.now.httpdate
digest("secret", "POST", "/v1/content", date)

While “Authentication” identifies your server to us, “User Identification” identifies your customer to the AI.

To maintain session continuity and personalization, you must handle two specific IDs correctly in every frontend request (Search, Autocomplete, Analytics).

ID TypeParameterDescription
Device IDclient_idRequired. A persistent identifier for the browser/device (e.g., a cookie ID). Must remain constant for the entire session, regardless of login state.
Auth IDcustomer_idOptional. The database ID of the logged-in user. Send this only when the user is logged in.

The client_id is the anchor. You must never change it mid-session, even if the user logs in or out.

sequenceDiagram
participant User
participant App
participant LuigiBox as LBX
Note over User, App: Anonymous browsing
User->>App: Views Homepage
App->>LuigiBox: Event with device_user_id COOKIE_123
Note over User, App: User logs in with auth_user_id USER_99
User->>App: Enters Credentials
App->>LuigiBox: Event with device_user_id COOKIE_123 and auth_user_id USER_99
Note over LuigiBox: History merges because device_user_id stays the same
Note over User, App: User logs out
User->>App: Clicks Logout
App->>LuigiBox: Event with device_user_id COOKIE_123
Note over LuigiBox: Session continues anonymously

We enforce rate limits to ensure stability. Limits are applied per Tracker ID (Account level) and per IP Address.

EndpointAccount LimitIP Limit
Content Updates500 req / min, 5 concurrent reqs-
Autocomplete800 req / min30 req / 5s
Search350 req / min30 req / 5s
Recommender60 req / 5s30 req / 5s

If you exceed a limit, you will receive a 429 Too Many Requests status. Your application must handle this gracefully.

We provide a Retry-After header indicating how many seconds you must wait.

sequenceDiagram
participant Client
participant API
Client->>API: POST content request
API-->>Client: 429 Retry-After 5 seconds
Note over Client: Wait 5 seconds
Client->>API: Retry content request
API-->>Client: 200 OK

Recommended Strategy:

  • Realtime APIs (Search, Autocomplete): Do not retry immediately. Discard the request.
  • Batch APIs (Content Updates): Use an exponential backoff strategy (wait Retry-After, then retry).

You should design your integration to be resilient to network failures.

CodeReasonTypeAction
401Auth FailedFatalCheck your Signature generation. The response body contains the string we expected vs. what you sent.
408TimeoutTransientSafe to retry once.
429ThrottlingTransientWait and retry (see above).
500Server ErrorFatalLog the error and contact support.
502Bad GatewayTransientUsually a deploy or network blip. Retry after 1s.
503Service UnavailableTransientCheck luigisboxstatus.com.

To ensure your integration is robust, we may enable Development Mode on your account during the integration phase.

What it does:

  • A small percentage of your requests will deliberately fail with various error codes (408, 429, 500).
  • These errors are marked in the JSON body as development_mode: true.

Why: This forces your developers to write proper error handling and retry logic before you go to production.