invory.app

Webhook API — Technical Documentation

Integrate your POS system with Invory to automatically sync sales and update inventory in real time at every checkout.

v1.0
REST / JSON
HTTPS Only

Endpoint

POST
https://platform.base44.com/api/apps/69302369dfe2ff6a9d4122c4/functions/posWebhook
Provide this endpoint to your POS provider as the webhook destination URL. It must be called on every checkout / receipt emission.

Authentication

Every request must include two identifiers, either as HTTP headers (recommended) or as JSON body fields (for legacy POS compatibility).

HeaderBody Field (alternative)Description
X-API-Keyapi_keyAPI Key generated from the Invory Integrations page
X-Business-Idbusiness_idUnique business identifier, visible on the Integrations page

The API Key and Business ID are available from Settings → POS Integrationswithin the end customer's Invory account.

Headers HTTP

http-headers
Content-Type: application/json
X-API-Key: YOUR_API_KEY_HERE
X-Business-Id: YOUR_BUSINESS_ID_HERE

Payload Structure

Top-level fields

items
array
required
Array of items sold in the order (see structure below)
sale_date
string (ISO 8601)
Date and time of the sale. E.g.: "2026-04-09T14:30:00Z". Defaults to current date if omitted.
order_id
string
Unique order ID in the POS system (useful for deduplication)
table_number
string
Table number or name. E.g.: "5", "Terrace 2"
cover_count
number
Number of covers
waiter_name
string
Waiter / operator name
payment_method
string
"cash", "card" or "other"
discount_percent
number
Applied discount as a percentage (e.g. 10 = 10%)
subtotal
number
Order subtotal
tax
number
Tax / VAT
total
number
Order total

Single item structure (object inside items)

name
string
required
Product name — must match the name in the Invory menu for automatic inventory deduction
quantity
number
required
Quantity sold
unit_price
number
Unit price
total_price
number
Item total price (if omitted, calculated as unit_price × quantity)
category
string
Product category. E.g.: "cocktail", "starters", "beverages"
payment_method
string
Per-item payment method (overrides the order-level one if present)

Full Payload Example

json
{
  "sale_date": "2026-04-09T14:30:00Z",
  "order_id": "ORD-001234",
  "table_number": "5",
  "cover_count": 2,
  "waiter_name": "Mario Rossi",
  "payment_method": "card",
  "discount_percent": 0,
  "notes": "",
  "items": [
    {
      "name": "Mojito",
      "category": "cocktail",
      "quantity": 2,
      "unit_price": 9,
      "total_price": 18
    },
    {
      "name": "Spaghetti Carbonara",
      "category": "primi",
      "quantity": 1,
      "unit_price": 14,
      "total_price": 14
    }
  ],
  "subtotal": 32,
  "tax": 3.52,
  "total": 35.52
}

Response

200 OK
Sale recorded successfully
json
{
  "status": "ok",
  "pos_system": "NomePOS",
  "message": "Processed 2 items. Updated 5 inventory records.",
  "items_processed": 2,
  "inventory_updated": 5,
  "order_id": "ORD-001234"
}
401
Invalid API Key
400
Malformed payload or missing required fields
404
No active POS configuration found for this Business ID
500
Internal error — contact support with the sent payload

Field Mapping (Custom Field Names)

If your POS system uses different field names from the defaults, you can configure a custom mapping from the Invory Integrations page without modifying the POS payload.

For example, if your POS sends product_name instead of name, simply configure the mapping and the webhook adapts automatically.

Remappable fields:

item_name → default: namequantity → default: quantityunit_price → default: unit_pricecategory → default: categorypayment_method → default: payment_methoddiscount → default: discountitems_array → default: itemssale_date → default: sale_date

Automatic Inventory Deduction

If a sold item name matches a product in the Invory menu with linked ingredients, the system automatically deducts the quantities from inventory.

Example:

1 "Mojito" is sold → Invory finds the recipe → deducts 50ml Rum, 30ml Lime Juice, 100ml Soda Water from inventory. Units are converted automatically (ml ↔ L, g ↔ kg).

Name matching is case-sensitive and must be identical between the POS and the Invory menu. If no match is found, the sale is still recorded without inventory deduction.

Test with cURL

bash
curl -X POST \
  https://platform.base44.com/api/apps/69302369dfe2ff6a9d4122c4/functions/posWebhook \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY_HERE" \
  -H "X-Business-Id: YOUR_BUSINESS_ID_HERE" \
  -d '{
    "order_id": "TEST-001",
    "sale_date": "2026-04-09T14:30:00Z",
    "payment_method": "card",
    "items": [
      {
        "name": "Mojito",
        "category": "cocktail",
        "quantity": 1,
        "unit_price": 9.00,
        "total_price": 9.00
      }
    ],
    "total": 9.00
  }'
Invory — Webhook API v1.0 · Technical support: support@invory.app