API endpoint reference

Every v1 endpoint with its scope, parameters, request body and an example response.

14 min read Updated Oct 17, 2026

Base URL https://api.leisurenexus.app/v1. All examples send Authorization: Bearer lnk_….

Stores

GET /locations

Scope catalog.read. Active stores, by name.

{ "data": [ { "id": "9f2c…2e11", "name": "Main Street", "code": "001", "address_line1": "120 Main St",
  "city": "Austin", "state": "TX", "postal_code": "78701", "phone": "5125550142", "timezone": "America/Chicago" } ] }

Departments

GET /departments

Scope catalog.read. Active departments with their active categories.

{ "data": [ { "id": "1b7e…90aa", "name": "Beverages", "image_url": "https://…/beverages.webp",
  "categories": [ { "id": "44c1…0b21", "name": "Soda" }, { "id": "8e02…77d4", "name": "Energy" } ] } ] }

Items

GET /items

Scope catalog.read. Active items, paged, sorted by name.

ParameterTypeMeaning
location_iduuidStore whose price to show; the key's store by default
department_iduuidOnly this department
barcodestringItems with this barcode (unit or pack)
updated_sincedate-timeChanged after this time
include_inactivebooleanInclude inactive items
searchstringName or SKU
sort / dirname, updated, sku / asc, descOrder
page / per_pageintegerPaging (≤ 200)
{
  "data": [
    {
      "id": "c3d0…51f9", "sku": "100245", "plu": null, "name": "Coca-Cola 20 oz", "description": null,
      "department_id": "1b7e…90aa", "category_id": "44c1…0b21", "department": "Beverages",
      "unit": "each", "is_weighed": false, "age_restriction": null, "ebt_eligible": true, "is_active": true,
      "price_cents": 249, "open_price": false, "image_url": "https://…/coke-20.webp",
      "barcodes": [
        { "barcode": "049000028911", "pack_qty": 1, "price_cents": null },
        { "barcode": "10049000028918", "pack_qty": 24, "price_cents": 4999 }
      ],
      "updated_at": "2026-10-16T18:22:41+00:00"
    }
  ],
  "meta": { "page": 1, "pages": 1, "per_page": 50, "total": 1, "from": 1, "to": 1 }
}

price_cents is the store's price when it has one, otherwise the item's base price. A barcode with pack_qty above 1 rings that many units, at its own price_cents if set. age_restriction is 18 or 21 for restricted items.

GET /items/{id}

Scope catalog.read. One item, same shape. Optional location_id.

Stock

GET /stock

Scope stock.read. Stock on hand for items that track inventory, at one store. Needs inventory switched on for the business.

ParameterTypeMeaning
location_iduuidStore; the key's store by default
item_id[]uuid, up to 200Only these items
page / per_pageintegerPaging
{ "data": [ { "item_id": "c3d0…51f9", "sku": "100245", "name": "Coca-Cola 20 oz",
  "location_id": "9f2c…2e11", "on_hand": 46, "in_stock": true, "updated_at": "2026-10-17 13:58:02" } ],
  "meta": { "page": 1, "pages": 1, "per_page": 50, "total": 1, "from": 1, "to": 1 } }

Customers

GET /customers

Scope customers.read. Active customers.

ParameterTypeMeaning
emailstringExact email address (emails are stored encrypted, so partial matches aren't possible)
phonestring10-digit US phone, any format
updated_sincedate-timeChanged after this time
searchstringFirst name, last name or company
sort / dirname, updatedOrder
{ "data": [ { "id": "5a1e…c0d2", "first_name": "Ana", "last_name": "Lopez", "company": null,
  "email": "ana@example.com", "phone": "5125550199", "loyalty_number": "5125550199", "is_active": true,
  "name": "Ana Lopez", "points_balance": 320, "house_account_balance_cents": null,
  "created_at": "2026-09-02T16:40:11+00:00", "updated_at": "2026-10-15T20:03:55+00:00" } ],
  "meta": { "page": 1, "pages": 1, "per_page": 50, "total": 1, "from": 1, "to": 1 } }

house_account_balance_cents is what the customer owes on their house account, or null when they have none.

GET /customers/{id}

Scope customers.read. One customer, same shape.

POST /customers

Scope customers.write. Adds a customer. Returns 201 with the customer.

FieldRules
first_nameRequired, up to 60 characters
last_nameUp to 60
companyUp to 120
emailValid email, unique in the business; saved lower-case
phone10-digit US number in any format; unique in the business
notesUp to 2,000
curl -X POST https://api.leisurenexus.app/v1/customers \
  -H "Authorization: Bearer lnk_…" -H "Content-Type: application/json" \
  -d '{"first_name":"Ana","last_name":"Lopez","email":"ana@example.com","phone":"(512) 555-0199"}'

PATCH /customers/{id}

Scope customers.write. Send only the fields to change. Returns 200 with the customer.

Sales and refunds

GET /orders

Scope orders.read. Completed and voided sales and refunds, newest first.

ParameterTypeMeaning
location_iduuidOne store; every store when empty
customer_iduuidOne customer's sales
since / untildate-timeCompleted at or after / before
searchstringReceipt number
sort / dircompleted, totalOrder
{
  "data": [
    {
      "id": "e7a9…1c33", "receipt_number": "001-01-000123", "type": "sale", "status": "completed",
      "location_id": "9f2c…2e11", "customer_id": "5a1e…c0d2", "order_type": null, "order_label": null,
      "subtotal_cents": 798, "discount_cents": 0, "tax_cents": 66, "total_cents": 864, "tip_cents": 0,
      "original_sale_id": null,
      "completed_at": "2026-10-17T14:05:00+00:00", "voided_at": null,
      "lines": [
        { "item_id": "c3d0…51f9", "sku": "100245", "name": "Coca-Cola 20 oz", "kind": "item",
          "quantity": 2, "unit_price_cents": 249, "total_cents": 498, "discount_cents": 0, "modifiers": [], "note": null },
        { "item_id": "7f11…aa20", "sku": "100871", "name": "Doritos Nacho 9.25 oz", "kind": "item",
          "quantity": 1, "unit_price_cents": 300, "total_cents": 300, "discount_cents": 0, "modifiers": [], "note": null }
      ],
      "payments": [
        { "type": "cash", "amount_cents": 500, "card_brand": null },
        { "type": "card", "amount_cents": 364, "card_brand": "visa" }
      ]
    }
  ],
  "meta": { "page": 1, "pages": 1, "per_page": 50, "total": 1, "from": 1, "to": 1 }
}
FieldValues
typesale or refund (a refund's original_sale_id points to the sale)
statuscompleted or voided (voided sales are left out of every total)
payments[].typee.g. cash, card, ebt_snap, gift_card, house_account

Card numbers and payment-processor references are never included.

GET /orders/{id}

Scope orders.read. One sale, same shape.

Wholesale orders

Needs the Wholesale ERP profile.

POST /sales-orders

Scope orders.write. Places a draft sales order for a business customer; prices come from the customer's price level. Returns 201.

FieldRules
customer_idRequired: the business customer
location_idStore or warehouse; the key's store by default
customer_poTheir purchase-order number, up to 40
notesUp to 1,000
lines1–500 lines, each with item_id or sku, and quantity (units)
{
  "customer_id": "0d4b…8e19",
  "customer_po": "PO-55120",
  "lines": [
    { "sku": "100245", "quantity": 48 },
    { "item_id": "7f11…aa20", "quantity": 24 }
  ]
}

Response:

{ "data": { "id": "a61c…f402", "number": "SO00042", "customer_id": "0d4b…8e19", "status": "draft",
  "customer_po": "PO-55120", "subtotal_cents": 18552, "tax_cents": 0, "total_cents": 18552,
  "invoice_number": null, "location_id": "9f2c…2e11", "customer": "Bar One", "contact": "Sam Ortiz",
  "order_date": "2026-10-17", "due_on": null, "shipped_at": null, "invoiced_at": null, "overdue": false,
  "notes": null, "lines": [ { "id": "…", "item_id": "c3d0…51f9", "name": "Coca-Cola 20 oz",
  "qty_milli": 48000, "unit_price_cents": 212, "line_cents": 10176, "tax_cents": 0,
  "unit_id": null, "unit_name": null, "unit_qty_milli": null } ], "source": "api" } }

Statuses move draft → confirmed → shipped → invoiced (or cancelled) as your team works the order in the back office. qty_milli is the quantity × 1,000.

GET /sales-orders/{id}

Scope orders.write. One wholesale order, same shape.

Still stuck? Email support@leisurenexus.com or send us a message — we're happy to help.