Developers
Data model
One shared database behind every app — understand records, relations and the patterns that repeat across the platform.
Quelixa's defining trait is a single shared database. There is no per-app data silo and no sync between modules — a customer, a product, a tax is one record that every app references. Understanding a few repeating patterns lets you predict the whole API.
One record, many apps#
The customer Sales quotes, the customer Invoicing bills and the customer Accounting reconciles are the same partner record. Update it once and every app reflects the change instantly.
Core entities#
These records appear across the platform and anchor most integrations.
| Entity | Resource | Notes |
| --- | --- | --- |
| Partner | partners | Customers, vendors and contacts — one model for all. |
| Product | products | Goods and services, with pricing and tax. |
| Invoice | invoices | Customer and vendor documents; move_type distinguishes them. |
| Journal entry | journal_entries | The double-entry posting behind every financial document. |
| Order | orders | Sales and purchase orders. |
| Account | accounts | Lines in the localized chart of accounts. |
Repeating patterns#
Once you've used one resource, the rest feel familiar because they share conventions:
- Documents have a state machine.
draft → confirmed/posted → done/cancelled. You move between states with actions, not by writing the field directly. - Money carries currency. Monetary fields come with the record's currency; amounts are in that currency.
- Relations are IDs with labels. A relation field returns
{ id, name }so you can render it without a second call. - Everything is auditable. Records carry created/updated metadata and an activity log.
Identifiers#
res_01HX… partner
prd_204 product
inv_01HX… invoiceIDs are stable, opaque strings. Don't parse them — treat them as handles. The legal, human-facing reference (an invoice number like INV/2026/0042) is a separate field assigned on confirmation.
Setting state to posted with a PATCH won't post the journal entry — it'll be rejected. Use the document's action (/confirm, /post) so the business logic runs. See the REST API for the create-then-act pattern.
If you're unsure how an integration should behave, do the task once in the interface and watch what changes. The API mirrors it: the same records move through the same states.