Getting StartedAPI reference
    Reference

    API Reference

    Headers, schemas, status codes, and rate limits for all Lehnz endpoints. For worked examples, see the integration guides.

    Base URL

    Every endpoint shares one base URL; all paths are versioned under /v1.

    https://api.lehnz.com

    API Keys

    Keys are generated from the Developer Access tab in your dashboard. Every request requires an X-API-KEY header with no Bearer prefix.

    TypePrefixWhere to use
    Publishablelehnz_pk_...Browser and client-side code
    Secretlehnz_sk_...Server-side only; never expose in the browser
    Using a secret key on a publishable endpoint (or vice versa) returns 403 Forbidden.

    Headers

    HeaderRequiredValue
    X-API-KEY✅ YesYour publishable or secret key
    Content-Type✅ Yesapplication/json

    Ingestion Endpoints

    All ingestion endpoints return 202 Accepted and use the same response envelope: { success, message, data: { accepted }, error }.

    POST /v1/items/upsert

    POSThttps://api.lehnz.com/v1/items/upsert

    Load your catalog before anything else; Lehnz can only recommend items it knows about. Re-call whenever items change. To hide or remove an item, upsert it with status: inactive or deleted rather than omitting it.

    Auth: Secret key (server-side only).

    Request Body Schema
    FieldRequiredDescription
    item_idStable item identifier.
    item_typeDomain-specific category, e.g. product or article.
    statusactive = recommendable; inactive = hidden; deleted = soft-deleted.
    attributesFree-form metadata (title, price, brand, category) used for filtering and ranking.
    created_atItem creation timestamp (ISO 8601).
    JSON Response
    {
    "success": true,
    "message": "items accepted",
    "data": { "accepted": 1 },
    "error": null
    }

    POST /v1/users/upsert

    POSThttps://api.lehnz.com/v1/users/upsert

    Load your users so recommendations can be personalised to them. Re-call when a profile changes or a user deactivates. Set status: inactive or deleted to preserve event history for analytics.

    Auth: Secret key (server-side only).

    Request Body Schema
    FieldRequiredDescription
    user_idStable user identifier (your application's user ID).
    statusactive = visible to recommendations; inactive = hidden, history kept; deleted = soft-deleted.
    created_atUser signup timestamp (ISO 8601).
    attributesFree-form metadata (segment, plan, locale).
    JSON Response
    {
    "success": true,
    "message": "users accepted",
    "data": { "accepted": 1 },
    "error": null
    }

    POST /v1/events/ingest

    POSThttps://api.lehnz.com/v1/events/ingest

    Stream every meaningful interaction so Lehnz learns in real time. Accepts a single event object or an array. When an interaction came from a recommendation, include recommendation_id to close the attribution loop.

    Auth: Publishable key (browser-safe).

    Request Body Schema (per event)
    FieldRequiredDescription
    user_idStable identifier. Anonymous shoppers use a client-generated UUID; signed-in shoppers use the application's real user ID.
    event_familyexposure | engagement | conversion | system
    event_nameLowercase event name (e.g. view, purchase).
    previous_user_idRequired only for identify events: the prior anonymous ID being aliased.
    item_idNull when the event is not tied to a specific item.
    recommendation_idInclude when the event was triggered by a served recommendation.
    event_idClient-supplied UUID; server assigns one if omitted.
    contextFree-form context object (device, locale, session).
    JSON Response
    {
    "success": true,
    "message": "events accepted",
    "data": { "accepted": 1 },
    "error": null
    }

    Recommendations

    One endpoint, many strategies. POST /v1/recommend serves every use case; the strategy field picks the algorithm.

    POST /v1/recommend

    POSThttps://api.lehnz.com/v1/recommend

    Auth: Publishable key (browser-safe). See the Strategies Guide for detailed schemas, modifiers, and request/response structures.

    Request Body Schema (Overview)
    FieldDescription
    strategyOne of 10 base strategies (default personalized).
    user_idRequired for user-based strategies.
    context_item_idRequired for item-to-item strategies like similar or frequently-bought-together.
    filtersAttribute filters, e.g. { "category": "shoes" }.
    limitItems to return (default 20, max 100).
    page1-indexed page number for pagination (default 1).
    JSON Response
    {
    "success": true,
    "message": "Success",
    "data": {
    "recommendation_id": "550e8400-e29b-41d4-a716-446655440000",
    "tenant_id": "glow-beauty-ng",
    "domain": "commerce",
    "strategy": "personalized",
    "mode": "behavioral",
    "results": [
    { "item_id": "prod_7", "score": 0.985, "reason": "behavioral_match", "metadata": { "brand": "Sony" } }
    ],
    "recommended_items": ["prod_7", "prod_3", "prod_22"],
    "pagination": { "page": 1, "limit": 20, "has_next": true },
    "latency_ms": 42.5
    },
    "error": null
    }

    Response Envelope

    All responses share the same structure:

    Success

    JSON Response
    {
    "success": true,
    "message": "...",
    "data": { }
    }

    Error

    JSON Response
    {
    "success": false,
    "message": "Human-readable error",
    "error": "Detail"
    }

    HTTP Status Codes

    StatusMeaning
    200 OKSynchronous request succeeded.
    202 AcceptedData queued for async processing (Ingestion endpoints). Events are typically available within seconds.
    400 Bad RequestValidation error; check the message field.
    401 UnauthorizedMissing or invalid X-API-KEY.
    403 ForbiddenWrong key type for this endpoint (e.g. using a publishable key on a server-only route) or tier restriction.
    429 Rate LimitedBack off and retry (see RateLimit-Reset header).
    500 Server ErrorInternal Server Error.

    Rate Limits

    • 1,000 requests per 15 minutes per organisation, shared across all API keys.
    • Auth endpoints (/auth/register, /auth/login) are capped at 10 requests per 15 minutes per IP.
    • To stay efficient during ingestion, batch multiple events into a single array.

    On 429 Rate Limited, retry with exponential backoff; the RateLimit-Reset header tells you when to try again.