Skip to main content

REST API: Integration with Accounting/Billing Systems — Retrieve Data from tSpoonLab

Technical guide to integrate purchases and sales from tSpoonLab with external accounting and billing systems.

Gustavo Vera avatar
Written by Gustavo Vera
Updated this week

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 vendors

  • idVendor (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 header order:<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.

Did this answer your question?