1. Receiving Purchase Orders, Goods Receipts, and Validating Invoices in tSpoonLab
tSpoonLab is ideal for creating supplier orders from the kitchen (based on planning, stock, or templates). Orders are recorded in the app and sent to the supplier via WhatsApp, email, or phone.
Goods receipts (delivery notes) are then registered in tSpoonLab. Besides cost control, this enables:
Recording receiving control points and lot numbers,
Posting stock entries,
Verifying delivered quantities and prices vs. the order.
From the Vendors screen you can also validate invoices against received delivery notes. That process creates an invoice, links its delivery notes, and then the invoice, taxes, and payments should be handled by your external billing system.
For purchases, you can export orders, delivery notes, or invoices.
To avoid duplicates, once consumed by the external system you should mark them as processed in tSpoonLab.
1.1 REST API: Login
Authenticate first; the login returns a token used in all subsequent requests.
[email protected] password=XXXXXXX url=https://app.tspoonlab.com/recipes/api authenticate="username=$username&password=$password" echo -n 'rememberme:' > rememberme.txt curl -v --data "$authenticate" "$url/login" >> rememberme.txt # Use the token curl -X PUT -v -H "$(cat rememberme.txt)" "$url/integration/call"
1.2 Select a Cost Center / Restaurant
Most calls run in the context of a cost center (order center).
Get the list of cost centers and IDs (see “Get a List of Cost Centers”).
Then include
order:<idOrderCenter>
in your headers:
rememberme: <token> order: 351583444167656299610202XXXXXXXXXXXX
2. Purchases — Export to External Systems
2.1 Retrieve Purchase Orders (not processed)
GET /integration/purchases/orders/pending?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true&idVendor=XXXXX
Query params
startDate
,endDate
(YYYY-MM-DD, inclusive)includeInternal
(bool, default true) — include internal vendorsidVendor
(optional) — filter by vendor ID
Response
class PurchaseOrder { String id; String numOrder; String idVendor; String vendor; String codeVendor; String accountVendor; String nif; Date date; String dateFormatted; // YYYY/MM/DD Date dateReception; String sentBy; String dateReceptionFormatted; // YYYY/MM/DD Double total; List<PurchaseOrderLine> listOrders; } class PurchaseOrderLine { String id; int position; String codeComponent; String idComponent; String codeVendorComponent; String component; String comment; // Base unit values Double quantity; String idUnit; String unit; Double cost; // If bought using a format boolean hasFormat; Double quantityFormat; String idUnitFormat; String unitFormat; Double costFormat; Double iva; // VAT rate String idCostType; String costType; String codeCostType; String accountCostType; String idBusinessLine; String businessLine; String codeBusinessLine; List<LineType> listTypes; // component families/types } class LineType { String id; String descr; }
Example
curl -X GET -v -H "$(cat rememberme.txt)" \ "$url/integration/purchases/orders/pending?startDate=2025-01-01&endDate=2025-12-31" \ | python -m json.tool
2.2 Mark Purchase Orders as Processed
After exporting, mark them to prevent re-export:
PUT /integration/purchases/orders/processed
Body
{"listIds":["<orderId1>","<orderId2>"]}
Example
curl -X PUT -d '{"listIds":["idFactura1","idFactura2"]}' \ -H "$(cat rememberme.txt)" -H 'Content-Type: application/json' \ "$url/integration/purchases/orders/processed"
2.3 Retrieve Purchase Deliveries (not processed)
GET /integration/purchases/deliveries/pending?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true&idVendor=XXXXX
Params same as orders.
Response
class PurchaseDelivery { String id; String idVendor; String vendor; String codeVendor; String accountVendor; String nif; String deliveryNum; Date date; // time_t String dateFormatted; // YYYY/MM/DD Double base; Double taxes; Double total; String idCostType; String costType; String codeCostType; String accountCostType; String idBusinessLine; String businessLine; String codeBusinessLine; String vendorType; String vendorTypeCode; boolean vendorTypeInternal; List<DeliveryTax> listTaxes; List<PurchaseDeliveryLine> listDeliveries; } class DeliveryTax { String id; short type; // 0:VAT, 1:Transport, 2:Discounts, 3:Other, -1: Base disc. Double base; // may be null (transport/discount/other) Double percent; // may be null (transport/discount/other) Double total; } class PurchaseDeliveryLine { String id; int position; String idComponent; String codeComponent; String component; String codeVendorComponent; String comment; boolean recibido; // Base unit Double quantity; String idUnit; String unit; Double cost; // Format purchase boolean hasFormat; Double quantityFormat; String idUnitFormat; String unitFormat; Double costFormat; Double iva; String idCostType; String costType; String codeCostType; String accountCostType; String idBusinessLine; String businessLine; String codeBusinessLine; List<LineType> listTypes; String idStore; String store; }
All deliveries (processed and not):
GET /integration/purchases/deliveries/all?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true&idVendor=XXXX
2.4 Mark Purchase Deliveries as Processed (and optionally lock)
PUT /integration/purchases/deliveries/processed?lock=true
Body
{"listIds":["<deliveryId1>","<deliveryId2>"]}
2.5 Lock Purchase Deliveries
PUT /integration/purchases/deliveries/lock
Body
{"listIds":["<deliveryId1>","<deliveryId2>"]}
2.6 Retrieve Purchase Invoices (not accounted)
GET /integration/purchases/invoices/pending?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true&onlyValidated=true&idVendor=XXXXX
Params
includeInternal
(bool, default true)onlyValidated
(bool, default false)idVendor
(optional)
Response
class PurchaseInvoice { String id; String idVendor; String vendor; String codeVendor; String accountVendor; String nif; String invoiceNum; boolean paid; boolean validated; String documentNum; String comment; Date date; Date dateAccounting; Date dateDue; String codePaymentType; String idCostTypeVendor; String costTypeVendor; String codeCostTypeVendor; String accountCostTypeVendor; String idDocument; String extDocument; String idBusinessLine; String businessLine; String codeBusinessLine; Double total; Double base; Double taxes; List<InvoiceTax> listTaxes; List<PurchaseDelivery> listDeliveries; List<CostTypeTax> listCostTypeTaxes; } class InvoiceTax { String id; short type; // 0:VAT, 1:Transport, 2:Discounts, 3:Other, -1: Base disc. Double base; Double percent; Double total; } class CostTypeTax { String id; // analysis account ID String descr; // analysis account description List<OrderVendorVat> listTaxes; } class OrderVendorVat { Double base; Double percent; Double total; }
All invoices (accounted or not):
GET /integration/purchases/invoices/all?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true&onlyValidated=false&idVendor=XXXX
Download associated invoice document
GET /exportFileBoundFile/{idDocument}.{extDocument}?id={idDocument}&rememberme={rememberme}
2.7 Mark Purchase Invoices as Accounted (and optionally lock)
PUT /integration/purchases/invoices/accounted?lock=true
Body
{"listIds":["<invoiceId1>","<invoiceId2>"]}
2.8 Mark Purchase Invoices as Not Accounted
PUT /integration/purchases/invoices/not/accounted
Body
{"listIds":["<invoiceId1>","<invoiceId2>"]}
2.9 Lock Purchase Invoices
PUT /integration/purchases/invoices/lock
Body
{"listIds":["<invoiceId1>","<invoiceId2>"]}
3. Sales — Export to External Systems
This section exports tSpoonLab sales outward (opposite direction to TPV/POS ingestion).
3.1 Retrieve Sales Deliveries (not accounted)
GET /integration/sales/deliveries/pending?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true
Response
class SalesDelivery { String id; String idCustomer; String customer; String customerCode; String address; String cp; String city; String nif; String contact; String phone; String contactAux; String phoneAux; String mail; String mailAux; String mailCC; String web; String customerType; String customerTypeCode; boolean customerTypeInternal; String invoiceNum; Date date; Double base; List<SalesDeliveryLine> listLines; // sent lines List<SalesDeliveryLine> listLinesPending; // pending to send } class SalesDeliveryLine { String id; int position; // Product sale (else null) String idComponent; String component; String codeComponent; // Menu sale (else null) String idMenu; String menu; String codeMenu; String codeCustomerProduct; // POS/PLU or custom sale code String comment; boolean sent; Double quantity; String idUnit; String unit; Double cost; Double iva; // VAT rate List<LineType> listTypes; String idCustomerGroup; String customerGroup; }
All sales deliveries:
GET /integration/sales/deliveries/all?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true
3.2 Mark Sales Deliveries as Accounted
PUT /integration/sales/deliveries/accounted
Body
{"listIds":["<deliveryId1>","<deliveryId2>"]}
3.3 Mark Sales Deliveries as Not Accounted
PUT /integration/sales/deliveries/not/accounted
Body
{"listIds":["<deliveryId1>","<deliveryId2>"]}
3.4 Lock Sales Deliveries
PUT /integration/sales/deliveries/lock
Body
{"listIds":["<deliveryId1>","<deliveryId2>"]}
3.5 Retrieve Sales Invoices (not accounted)
GET /integration/sales/invoices/pending?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD&includeInternal=true
Response
class SalesInvoice { String id; String idCustomer; String customer; String codeCustomer; String accountCustomer; String nif; String documentNum; String invoiceNum; boolean paid; String comment; Date date; Date dateAccounting; Date dateDue; String codePaymentType; String idCostTypeVendor; // analysis account of customer String costTypeVendor; String codeCostTypeVendor; String accountCostTypeVendor; String idDocument; String extDocument; Double total; Double base; Double taxes; List<InvoiceTax> listTaxes; // same shape as purchases List<CostTypeTax> listCostTypeTaxes; // same shape as purchases List<SalesDelivery> listDeliveries; }
3.6 Mark Sales Invoices as Accounted
PUT /integration/sales/invoices/accounted
Body
{"listIds":["<invoiceId1>","<invoiceId2>"]}
3.7 Mark Sales Invoices as Not Accounted
PUT /integration/sales/invoices/not/accounted
Body
{"listIds":["<invoiceId1>","<invoiceId2>"]}
3.8 Lock Sales Invoices
PUT /integration/sales/invoices/lock
Body
{"listIds":["<invoiceId1>","<invoiceId2>"]}
4. Creating Purchase Orders in tSpoonLab (from an external system)
4.1 Identify the Vendor
First, obtain the vendor ID:
GET /listVendorsPaged
(See Vendors & Purchases documentation for details.)
In production-center setups, a vendor may be linked to a client of the production center; the orderCenter
field indicates where you will place the order.
Select the target idVendor
from the response.
4.2 Create the Purchase Order
POST /integration/purchases/orders
Body
class NewPurchaseOrder { String idVendor; // vendor ID Date dateSend; // order send date Date dateReception; // expected reception date List<NewPurchaseOrderLine> listLines; } class NewPurchaseOrderLine { String idComponent; // ingredient/material ID Double quantity; // required (base unit) }
listLines
: items to purchase.To obtain
idComponent
, check the vendor’s sellable products (VendorComponent
) as explained in Vendors & Purchases (section 1.8).
Response
class IdWrapper { String id; } // purchase order ID
4.3 Mark the Order as Sent
Once you’ve communicated the order to the vendor (outside this API), mark it sent:
PUT /vendorOrder/{idProvCom}/sent
HTTP 200 on success; no body.
General Notes & Best Practices
Authentication: Always include
rememberme
and the cost center headerorder:<idOrderCenter>
.Date ranges:
startDate
/endDate
are inclusive.Deduplication: After exporting to your external system, mark as processed/accounted/locked to avoid re-export.
Internal entities:
includeInternal=true
includes vendors/customers flagged as internal (useful in production-center scenarios).VAT & analysis accounts: Both purchases and sales return VAT breakdowns and optional analysis account (cost/revenue) information.
Documents: When present, invoice documents can be downloaded via
exportFileBoundFile
.