Alya Books

    Developer docs

    REST API, webhooks, MCP server and CLI for UAE e-invoicing

    Products and bundles

    Items used on invoice lines, with VAT category, unit and price.

    Products (and services) are the items the invoice editor and the API can put on lines. Referencing an item by itemId on an invoice line keeps reporting per product consistent; the line still carries its own description, price and VAT values.

    Fields

    FieldNotes
    name, nameAr, descriptionNames; the Arabic name is used on bilingual PDFs
    typeproduct (default) or service
    sku, barcodeYour codes; GET /products/valid-code?sku= checks that a SKU is free, POST returns 409 on a duplicate
    unitCodeUN/ECE Rec 20 (EA, HUR, KGM, …), default EA
    unitPrice, currencyNet price, default currency AED
    taxCategory, taxRatestandard (5 %), zero_rated, exempt, reverse_charge; the rate defaults from the category
    hsnCodeHS code (commodity classification, BT-158)
    itemNumberYour item number; the item number series allocates them in the app
    glnGS1 GLN / GTIN, 8–14 digits
    costPricePurchase price; the response adds margin in percent of the net price
    trackInventory, inventoryCount, lowStockThresholdStock is reduced by the invoiced quantity when an invoice leaves draft (not for test documents or credit notes)
    categoryFree-text group
    isActiveInactive items stay on old invoices but are hidden from pickers

    Routes

    curl "$BASE/products?keyword=consulting&sort=unitPrice&order=desc" -H "X-API-KEY: $KEY"
    curl -X POST "$BASE/products" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
      -d '{ "name": "Consulting hour", "type": "service", "sku": "CONS-H", "unitCode": "HUR", "unitPrice": 500 }'
    curl -X POST "$BASE/products/import" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" -d '{ "products": [ … ] }'
    

    DELETE /products/{id} deactivates items that are used on invoice lines instead of deleting them.

    Price lists

    A price list holds net prices per item with optional quantity breaks, a validity window, and either isDefault: true (applies to every customer without an assignment) or a list of customerIds. A customer can also carry defaultPriceListId.

    curl -X POST "$BASE/price-lists" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" -d '{
      "name": "Wholesale 2027", "validFrom": "2027-01-01", "validTo": "2027-12-31",
      "items": [{ "itemId": "…", "unitPrice": 90 }, { "itemId": "…", "unitPrice": 80, "minQuantity": 10 }],
      "customerIds": ["…"]
    }'
    curl "$BASE/products/{id}/price?customerId=…&quantity=12&date=2027-03-01" -H "X-API-KEY: $KEY"
    

    GET /products/{id}/price resolves the price the editor would use: customer-assigned lists (highest priority first), then default lists, then the item's own price; within a list the row with the largest minQuantity that fits wins. The response names the source and the list. PUT /price-lists/{id}/items and PUT /price-lists/{id}/customers replace the prices or the assignment in one call.

    Invoice inputs still take an explicit unitPrice per line; price lists are a lookup for your integration (and for the editor), not a server-side override.

    Bundles

    A bundle is a set of items with quantities. isSplittable: true (default) means the bundle is invoiced as one line per component, each priced through the price lists; otherwise it is one line at the bundle price (priceMode: "sum" of components or "fixed" with fixedPrice, plus the bundle's own VAT category).

    curl -X POST "$BASE/bundles" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
      -d '{ "name": "Starter kit", "items": [{ "itemId": "…", "quantity": 3 }, { "itemId": "…", "quantity": 1 }] }'
    curl "$BASE/bundles/{id}/lines?quantity=2&customerId=…" -H "X-API-KEY: $KEY"
    

    GET /bundles/{id}/lines returns ready-made items[] for POST /invoices. MCP: expand_bundle, get_product_price, create_price_list, create_bundle.