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#

No duplication, no sync

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…   invoice

IDs 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.

Don't write state fields directly

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.

Model your integration on the app

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.