Endpoint reference

Every public endpoint, its required scope, and the safe fields it returns. All paths are relative to https://api.luxpos.lu/api/v1 and need a Bearer API key. Prefer clicking through requests? Use the interactive API Reference.

71 endpoints · 14 resources·Scopes & security model

Business & Locations

The business your key belongs to and its branches.

GET/public/mebusiness:read

The business this API key belongs to.

Fieldsid, name, currency, country, slug, status

GET/public/locationsbusiness:read

List business locations / branches (paginated).

Querypage limit

Fieldsid, locationNumber, name, code, street, houseNumber, city, postalCode, country, phone, email, vatNumber, latitude, longitude, isHeadquarters, isActive, createdAt

GET/public/locations/:idbusiness:read

Get a single location / branch.

FieldsSame fields as the location list.

Products & Inventory

Read the catalogue and per-location stock; create products and post signed stock adjustments.

GET/public/productsproducts:read

List products (paginated).

QuerycategoryId search page limit

FieldsCatalogue fields: id, name, description, sellingPrice, sku, ean, categoryId, images (array of image URLs), isForSale, stockQuantity …

GET/public/products/:idproducts:read

Get a single product (same fields as the list, incl. images[]).

GET/public/product-categories/treeproducts:read

All product categories (flat list, ordered by position).

GET/public/products/:id/inventoryproducts:read

Per-location stock for a product.

FieldsproductId, trackInventory, totalQuantity, lowStockAlert, locations[locationId, locationName, locationNumber, quantity, lowStockAlert, updatedAt]

POST/public/productsproducts:write

Create a product.

I/OBody: name, sellingPrice, description?, sku?, ean?, purchasePrice?, vatRate?, vatPercent?, trackInventory?, stockQuantity?, lowStockAlert?, categoryId?, folderIds? (product folder UUIDs to file it under), images? (array of image URLs), isForSale?

IdempotentSend an Idempotency-Key header to safely retry.

PATCH/public/products/:idproducts:write

Update a product.

I/OBody: any of the create fields. images? (array of URLs) replaces the whole image list. folderIds? (array of folder UUIDs) replaces the product's folder assignment ([] removes it from all folders).

POST/public/products/:id/imageproducts:write

Upload an image file (multipart/form-data, field "image", ≤10MB jpeg/png/gif/webp) and append it to the product's images[].

I/OBody (multipart): image=<file>. Returns: the updated product with the new URL appended to images[].

DELETE/public/products/:idproducts:write

Delete a product (soft delete — lets you walk back a bad bulk import). Returns 204.

POST/public/products/:id/inventoryinventory:write

Adjust stock by a signed delta (writes an inventory audit log).

I/OBody: delta (signed int), locationId?, reason?, note?. Returns: productId, locationId, delta, totalQuantity, locationQuantity

IdempotentSend an Idempotency-Key header to safely retry.

POST/public/product-categoriesproducts:write

Create a product category — top-level, or nested under a parent via parentId.

I/OBody: name, description?, image? (URL), color?, parentId? (nest under an existing category), sortOrder?. Returns: the created category (id, name, parentId, path, …).

IdempotentSend an Idempotency-Key header to safely retry.

PATCH/public/product-categories/:idproducts:write

Update a category — rename, recolor, or reparent it.

I/OBody: name?, description?, image?, color?, sortOrder?, parentId? (reparent; pass null to move to top level — the subtree path is rewritten).

DELETE/public/product-categories/:idproducts:write

Delete a category. Fails (400) if it has active products; use ?force=true to delete one that still has empty sub-categories. Returns 204.

Queryforce

Product Folders (Dossiers)

Organise the catalogue into a folder tree (dossiers) — separate from product categories. Create folders, nest sub-folders, and file products into them during a bulk import.

GET/public/product-foldersproducts:read

List product folders (flat, ordered by sort position).

Fieldsid, name, color, icon, isVisible, sortOrder, parentId, path, productCount

GET/public/product-folders/treeproducts:read

Product folders as a nested tree (parent → children).

FieldsEach node: id, name, color, icon, isVisible, sortOrder, parentId, path, productCount, children[] (recursive).

POST/public/product-foldersproducts:write

Create a folder — top-level, or nested under a parent via parentId.

I/OBody: name, color?, icon?, parentId? (nest under an existing folder), sortOrder?, isVisible?. Returns: the created folder (id, name, color, icon, isVisible, sortOrder, parentId, path).

PATCH/public/product-folders/:idproducts:write

Update a folder — rename, recolor, re-icon, toggle visibility, or reparent it.

I/OBody: name?, color?, icon?, isVisible?, sortOrder?, parentId? (reparent; pass null to move to top level — the subtree path is rewritten).

DELETE/public/product-folders/:idproducts:write

Delete a folder. Fails (400) if it has sub-folders; use ?force=true to delete one with sub-folders. Returns 204.

Queryforce

POST/public/product-folders/:id/productsproducts:write

Assign products to a folder (replaces the folder's product set).

I/OBody: productIds (array of product UUIDs). Returns: the updated folder (id, name, …, productCount).

Customers

Read profiles and visit history; create and link customers without duplicating people.

GET/public/customerscustomers:read

List customers (paginated).

Querysearch page limit

GET/public/customers/:idcustomers:read

Get a single customer with visit history.

POST/public/customerscustomers:write

Create a customer (links to an existing person by email/phone instead of duplicating).

IdempotentSend an Idempotency-Key header to safely retry.

PATCH/public/customers/:idcustomers:write

Update a customer that belongs to your business.

Transactions & Sessions

The raw ledger of the register — every POS sale, line item, and cash-drawer session.

GET/public/transactionstransactions:read

List POS transactions (paginated).

Queryfrom to page limit

GET/public/transactions/:idtransactions:read

Get a single transaction with its line items.

GET/public/sessionstransactions:read

List POS sessions (paginated).

Queryfrom to page limit

GET/public/sessions/:idtransactions:read

Get a single POS session with its transactions.

Reports

Aggregated revenue reports and breakdowns, ready to drop into a dashboard.

GET/public/reports/summaryreports:read

Revenue summary KPIs for a date range.

Queryfrom to

GET/public/reports/by-productreports:read

Revenue broken down by product.

Queryfrom to

GET/public/reports/by-categoryreports:read

Revenue broken down by product category.

Queryfrom to

GET/public/reports/by-cashierreports:read

Revenue broken down by cashier.

Queryfrom to

GET/public/reports/monthly-gridreports:read

Monthly aggregated revenue grid.

Queryfrom to

Invoices

Issued sales invoices with line items — for accounting and reconciliation.

GET/public/invoicesinvoices:read

List sales invoices (paginated). Filter by customerId, buyerEmail (exact, case-insensitive) or externalRef to find a specific document instead of paging through everything. Every filter is applied inside your own business only.

Queryfrom to status customerId buyerEmail externalRef page limit

Fieldsid, locationId, customerId, invoiceNumber, invoiceType, status, creditNoteId (the invoice a CREDIT_NOTE credits), externalRef (your own reference), invoiceDate, dueDate, paidAt, buyerName, subtotalNet, totalVat, totalGross, discount, totalAmount, currency, exchangeRate, baseAmount (EUR-equivalent of totalAmount), structuredCommunication, createdAt

GET/public/invoices/:idinvoices:read

Get a single sales invoice with line items and VAT breakdown.

FieldsList fields (incl. currency, exchangeRate, baseAmount) + buyer address, buyerVatNumber, vatInclusive, paymentMethod, notes, customerNotes, pdfUrl (stable capability link), pdfDownloadUrl (fresh 15-min presigned URL, null until the PDF exists), items[], vatBreakdown[]. Never Stripe ids, fees or netPayoutAmount.

GET/public/invoices/:id/pdf-urlinvoices:read

Get a fresh, short-lived download URL for the invoice PDF. Returns { url, expiresIn: 900 } — a NEW presigned URL each call (valid 15 min). Invoice PDFs are private; direct object URLs are no longer public, so fetch a link here on demand instead of storing one.

POST/public/invoicesinvoices:write

Create a sales invoice (draft, or finalized when finalize=true). Pass currency (ISO-4217, e.g. "USD") to bill in a foreign currency — conversion to EUR is automatic (ECB rate on the invoice date) and returned as exchangeRate + baseAmount.

I/OBody: buyerName, items[] (description, quantity, unitPrice, vatPercent?, discount?), customerId?, buyer address/VAT?, invoiceDate?, dueDate?, invoiceType?, vatInclusive?, discount?, notes?, currency? (3-letter ISO-4217, default EUR), externalRef? (max 128 chars, your own reference, filterable), finalize?. Returns: the invoice incl. currency, exchangeRate, baseAmount, customerId, externalRef.

IdempotentSend an Idempotency-Key header to safely retry.

POST/public/invoices/:id/credit-noteinvoices:write

Issue a credit note (Avoir) for a confirmed or paid invoice. IMPORTANT: a credit note is stored with POSITIVE amounts, exactly like an invoice. Subtract it in your own books via invoiceType === CREDIT_NOTE. Never expect negative numbers.

I/OBody (all optional, an empty body is valid): externalRef? (not inherited from the credited invoice), notes? (defaults to “Credit note for invoice <number>”), finalize? (assigns the sequential number, renders the PDF and settles the original when fully covered). Returns: the credit note, with creditNoteId pointing at the invoice it credits.

IdempotentSend an Idempotency-Key header to safely retry.

PATCH/public/invoices/:idinvoices:write

Update a draft sales invoice.

I/OBody: same optional buyer/date/type/discount/notes fields as create, plus externalRef? (empty string clears it).

Expenses

Purchase and cost records for bookkeeping.

GET/public/expensesexpenses:read

List expenses (paginated).

Querystatus categoryId from to search page limit

Fieldsid, expenseNumber, description, amount, netAmount, vatAmount, vatPercent, expenseDate, status, categoryId, category, vendorName, vendorVatNumber, paymentMethod, notes, isRecurring, paidAt, createdAt

GET/public/expenses/:idexpenses:read

Get a single expense.

POST/public/expensesexpenses:write

Create an expense (draft).

IdempotentSend an Idempotency-Key header to safely retry.

PATCH/public/expenses/:idexpenses:write

Update a draft expense.

DELETE/public/expenses/:idexpenses:write

Delete a draft expense.

Tax

Period tax overview — revenue, deductible VAT, net liability, and P&L.

GET/public/tax/overviewtax:read

Tax overview for a period (revenue, deductible VAT, net liability, P&L).

Querytype year month quarter

Banking

Read-only bank accounts and the reconciled transaction feed.

GET/public/bank-accountsbanking:read

List bank accounts (paginated).

Querypage limit

Fieldsid, name, iban, currency, provider, institutionName, status, lastSyncedAt, createdAt. Never the provider/connection ids.

GET/public/bank-accounts/:idbanking:read

Get a single bank account.

GET/public/bank-transactionsbanking:read

List bank transactions (paginated).

QueryaccountId status from to page limit

Fieldsid, bankAccountId, bookedAt, valueDate, amount, currency, counterpartyName, counterpartyIban, remittance, structuredComm, status, matchedInvoiceId, createdAt. Never the raw provider payload.

GET/public/bank-transactions/:idbanking:read

Get a single bank transaction.

Staff

The team roster — safe fields only.

GET/public/staffstaff:read

List staff (id, name, role only — never email or phone).

Fieldsid, firstName, lastName, title, order, isActive

Loyalty

Loyalty cards and members with their live points and stamp balances.

GET/public/loyalty/cardsloyalty:read

List loyalty cards / members (paginated).

Querypage limit

Fieldsid, code, currentStamps, totalStamps, rewardsRedeemed, points, appointmentsCompleted, spinTokens, lastVisitAt, isActive, createdAt, customer{id, firstName, lastName}

GET/public/loyalty/cards/:idloyalty:read

Get a single loyalty card.

POST/public/loyalty/lookuployalty:read

Resolve a scanned wallet-pass QR / card code to the member and their live balance.

FieldscardId, code, customerId, firstName, lastName, type, points, currentStamps, stampsRequired, rewardDescription, rewardReady

POST/public/loyalty/cards/:id/stampsloyalty:write

Add stamps at checkout. Auto-resets a full card and mints the reward coupon; the wallet pass updates automatically.

POST/public/loyalty/cards/:id/stamps/removeloyalty:write

Remove stamps (correction).

POST/public/loyalty/cards/:id/pointsloyalty:write

Adjust points by a signed delta (earn on the ticket total, or deduct). Balance floors at 0.

POST/public/loyalty/cards/:id/redeemloyalty:write

Redeem a full stamp card — deducts the required stamps and returns the reward for the till to apply.

POST/public/loyalty/coupons/:code/redeemloyalty:write

Redeem a single-use loyalty coupon by its code.

Website Builder

Build a full website programmatically: branding, source code (CSS / head HTML / JS), pages (visual blocks OR raw HTML), themes and publishing. The site is created on first use. Requires the Shop entitlement.

GET/public/sitesite:read

Get the site config + page list. Creates the site (with default pages) on first call.

Fieldsid, isEnabled, siteName, logoUrl, faviconUrl, primaryColor, secondaryColor, accentColor, fontFamily, heroImageUrl, metaTitle, metaDescription, ogImageUrl, footerText, socialLinks, customCss, customHeadHtml, customJs, themeId, pages[], customDomain

PATCH/public/sitesite:write

Update branding, source code and SEO. Set isEnabled=true to publish the whole site.

I/OBody (all optional): isEnabled, siteName, logoUrl, faviconUrl, primaryColor, secondaryColor, accentColor, fontFamily, heroImageUrl, metaTitle, metaDescription, ogImageUrl, footerText, socialLinks, googleAnalyticsId, facebookPixelId, customCss, customHeadHtml (injected in <head>), customJs (before </body>).

GET/public/site/pagessite:read

List all pages, ordered.

GET/public/site/pages/:slugsite:read

Get a single page by slug.

Fieldsid, title, slug, isHome, isPublished, showInNav, order, metaTitle, metaDescription, ogImageUrl, blocks[], renderMode ('BLOCKS'|'CODE'), customHtml

POST/public/site/pagessite:write

Create a page. Provide `blocks` for the visual builder, OR renderMode='CODE' + customHtml for a raw-HTML page.

I/OBody: title, slug, showInNav?, isPublished?, metaTitle?, metaDescription?, renderMode? ('BLOCKS'|'CODE'), blocks? (array of { type, order, config } — see /public/site/block-types), customHtml? (required when renderMode='CODE'). Max 10 custom pages.

IdempotentSend an Idempotency-Key header to safely retry.

PATCH/public/site/pages/:pageIdsite:write

Update a page — replace its blocks, switch to CODE mode, edit SEO, publish/unpublish, toggle nav, reorder.

I/OBody (all optional): title, slug, isPublished, showInNav, order, metaTitle, metaDescription, ogImageUrl, renderMode ('BLOCKS'|'CODE'), blocks (replaces the whole array), customHtml (required when setting renderMode='CODE').

DELETE/public/site/pages/:pageIdsite:write

Delete a page. Fixed pages (home/services/gallery/blog/contact/booking) cannot be deleted — unpublish them instead. Returns 204.

GET/public/site/themessite:read

List available themes with their design tokens and editable source code (css / headHtml / js).

Fieldsid, key, name, description, previewImageUrl, tokens, pages, css, headHtml, js, price

POST/public/site/apply-themesite:write

Apply a theme: maps its tokens + source code onto the site and clones its pages (existing pages kept; slug collisions get a numeric suffix).

I/OBody: themeKey (e.g. 'starter' or 'vitrine'). Returns: the updated site with pages.

IdempotentSend an Idempotency-Key header to safely retry.

GET/public/site/block-typessite:read

Catalog of every block type and its default config — the shape a client (or an AI) needs to fill a page's blocks[].

Fieldsblocks[]: { type, category, description, defaultConfig }

Shop

Online shop settings (storefront). Products themselves are managed via the Products endpoints (products:write). Requires the Shop entitlement.

GET/public/shopshop:read

Get the shop settings for your business. 404 until a shop is created via PATCH.

Fieldsid, slug, name, description, mode (B2C|B2B|HYBRID), currency, status, primaryColor, logoUrl, bannerUrl, offersShipping, shippingFlatRate, freeShippingAbove, offersPickup, pickupAddress, showPricesToGuests, b2bRequireApproval, sellsServices, sellsGiftCards, invoiceMode, siteId, locationId, metaTitle, metaDescription, productCount

PATCH/public/shopshop:write

Upsert the shop: creates it on the first call (name defaults to the business name), then updates it. Set status=ACTIVE to publish. Link a builder site with siteId.

I/OBody (all optional): name, mode, slug, description, primaryColor, currency, offersShipping, shippingFlatRate, freeShippingAbove, offersPickup, pickupAddress, invoiceMode, sellsServices, sellsGiftCards, showPricesToGuests, b2bRequireApproval, status, logoUrl, bannerUrl, siteId (your WhiteLabelSite id), locationId, metaTitle, metaDescription.

IdempotentSend an Idempotency-Key header to safely retry.