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_type | What it is | Side |
|---|---|---|
quotations | ใบเสนอราคา — quotation | Sales |
invoices | ใบแจ้งหนี้ — invoice (flagged isTaxInvoice when it doubles as ใบกำกับภาษี) | Sales |
receipts | ใบเสร็จรับเงิน — receipt | Sales |
billing_notes | ใบวางบิล — billing note, batching invoices for one collection | Sales |
credit_notes | ใบลดหนี้ — credit note | Sales |
purchase_orders | ใบสั่งซื้อ — purchase order | Purchase |
expenses | ค่าใช้จ่าย — expense / supplier bill | Purchase |
billing_notes_expenses | ใบวางบิลฝั่งซื้อ — billing note received | Purchase |
credit_notes_expenses | ใบลดหนี้ฝั่งซื้อ — credit note received | Purchase |
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.