← PEAK integration

Working with PEAK documents

PEAK organizes bookkeeping around documents. Each family has its own endpoint, and the Daslab tools mirror that: every document tool takes a document_type naming the family.

The document families

document_typeWhat it isSide
quotationsใบเสนอราคา — quotationSales
invoicesใบแจ้งหนี้ — invoice (flagged isTaxInvoice when it doubles as ใบกำกับภาษี)Sales
receiptsใบเสร็จรับเงิน — receiptSales
billing_notesใบวางบิล — billing note, batching invoices for one collectionSales
credit_notesใบลดหนี้ — credit noteSales
purchase_ordersใบสั่งซื้อ — purchase orderPurchase
expensesค่าใช้จ่าย — expense / supplier billPurchase
billing_notes_expensesใบวางบิลฝั่งซื้อ — billing note receivedPurchase
credit_notes_expensesใบลดหนี้ฝั่งซื้อ — credit note receivedPurchase

The purchase side mirrors the sales side one-for-one. If you know how invoices work, expenses work the same way with the counterparty reversed.

Addressing a document

Every document has two identities: a PEAK id (a UUID) and a code — the human-facing running number the business actually says out loud, like IVS202308008. peak_get_document accepts either. Prefer the code when a person gave you one; prefer the id when you got it from a list call.

Read first, then create

peak_create_document posts the payload to PEAK as-is. The field shape differs per family, so read an existing document of the same family first (peak_get_document) and mirror it. Contacts and products are referenced by their PEAK ids, so resolve them with peak_list_contacts / peak_list_products before composing the payload.

Documents are chained rather than duplicated: a receipt is normally created from an invoice, an expense from a purchase order. Creating both ends independently leaves the books with two unlinked documents and no settlement.

Dates, VAT, and the chart of accounts

Dates are yyyyMMdd strings, not ISO timestamps. Amounts come as preTaxAmount, vatAmount, netAmount, plus remainAmount — what is still outstanding — which is the field to read when asking "who owes us money".

Whether the business is VAT-registered at all comes from peak_get_business (isVat). peak_list_account_codes returns the chart of accounts for journal work.

Limits worth respecting

PEAK meters API usage against a credit balance (peak_get_api_credit) and caps concurrency at 10 GET and 5 POST requests in flight per User Token; the client-token mint is capped at 10/minute and file uploads at 2/minute. Over the line the API answers 429 with retryAfterSeconds.

The practical consequence: fetch a date range once with peak_list_documents rather than looping single reads, and page through results instead of raising limit indefinitely.