Data model
Qoyod organizes its data around five entities that every inventory integration will encounter: Product, Inventory location, Account, Invoice, and Contact. Understanding what Qoyod considers each entity to be -- and which fields identify it -- is the prerequisite for mapping your integrated system's records correctly. This page does not cover sync directions or conflict handling; those are addressed in sync directions.
Core entities
The table below names each entity, the Qoyod API tag that exposes it, and the fields most relevant to integration work. Full field details are in the Qoyod API reference.
| Entity | Qoyod API tag | Key fields | Notes |
|---|---|---|---|
| Product | products | id, name_en, name_ar, sku, type, track_quantity | type enum controls record classification |
| Inventory location | inventories | id, name, ar_name, is_default, account_id | One record per physical or logical warehouse |
| Account | accounts | id, code, name_en, name_ar, account_kind, parent_kind, branch_kind | Leaf nodes in the chart of accounts hierarchy |
| Invoice | invoices | id | Formal request for payment from a customer |
| Contact | contacts | id | Represents a Customer or Vendor |
Product is the central entity for inventory integrations. Each product record has a
type field that classifies it as one of: Product, Service, Expense, RawMaterial,
or Recipe. This classification determines how Qoyod treats the record in accounting and
inventory contexts -- for example, only records with track_quantity set to 1 have
their stock levels managed across inventory locations.
Inventory location represents a physical or logical place where stock is held. Each
location has a unique Qoyod ID. When a product has track_quantity enabled, its stock
level is tracked per inventory location. The is_default field identifies the location
Qoyod uses when no explicit location is specified.
Account is a leaf node in Qoyod's chart of accounts. Accounts are organized in a
three-level hierarchy: main account (identified by parent_kind) -> branch account
(identified by branch_kind) -> sub-account (identified by account_kind). Products
reference accounts via sales_account_id and expense_account_id, which connect product
transactions to the correct ledger entries.
Invoice is a commercial document that records a formal request for payment from a Customer for goods or services delivered. Every invoice Qoyod creates generates corresponding debit and credit entries in the general ledger automatically.
Contact is the party record that represents either a Customer (a party that purchases from the merchant) or a Vendor (a party the merchant purchases from). Invoices and bills reference a Contact as the counterparty to the transaction.
How entities relate
The five entities connect to each other in ways that affect how data must be structured when you synchronize between your integrated system and Qoyod.
A Product belongs to a Category (via category_id). When a product has
track_quantity set to 1, its current stock levels appear nested within the product
record under inventories -- one entry per inventory location, each with a stock value.
An Inventory location holds the stock of Products. The relationship is many-to-many: each product can have stock across multiple locations, and each location can hold many products. Qoyod populates this relationship when stock-affecting transactions occur; the integrator does not manage it directly.
An Invoice references one or more Products as line items and exactly one Contact as the counterparty. When Qoyod records an invoice, it decrements stock for tracked products in the relevant inventory location and posts entries to the accounts linked to those products.
An Account sits at the leaf of the chart of accounts hierarchy. Products reference
specific accounts for sales and cost-of-goods-sold entries. Inventory locations reference
an account via account_id for inventory-related transactions.
Mapping your data to Qoyod
When you build an integration, your task is to decide which records in your integrated system correspond to which Qoyod entities, and which fields carry the correspondence.
Identifying records across systems
Qoyod assigns every entity a numeric id when the record is created. Your integration
should store this Qoyod ID on the corresponding record in your integrated system so that
future updates can target the correct Qoyod record without a lookup.
The product type enum
The type field on a product record determines its classification in Qoyod. The five
values are:
| Value | Meaning |
|---|---|
Product | A physical good that can be bought and sold. Default when type is omitted on creation. |
Service | An intangible offering that can be sold but does not have stock. |
Expense | A cost item that is not sold to customers. |
RawMaterial | A component used as input in a Recipe. |
Recipe | A compound product assembled from RawMaterial ingredients. |
When mapping your integrated system's product catalog to Qoyod, assign type based on
what the record represents. A digital download is a Service. A bundle composed of
components may be a Recipe. The type field is set on creation and ignored on update,
so the classification must be correct from the first synchronization.
Required fields by entity
- Product: The
productwrapper object is required. Send at minimumname_enorname_arand atypevalue to produce a meaningful record. - Inventory location:
nameis required. All other fields are optional. - Account:
en_name,ar_name,account_kind,parent_kind, andbranch_kindare required.codeis auto-generated if omitted.
Tracking Qoyod stock levels
To read current stock levels from Qoyod, retrieve a product record. The inventories
array in the product response includes one entry per inventory location, with the current
stock value at that location. Stock levels change in Qoyod when invoices, bills,
inventory transfers, or stock takes are recorded -- they are not written directly by the
integration.
Related
- Sync directions -- which system initiates data flow and what each direction requires.
- Pagination and filtering -- how to page through large entity lists when polling Qoyod.
- Qoyod API reference -- full field-level documentation for all entities.