# Accounting Data Model: How Entities Connect

Understanding how accounting entities relate to each other is essential for building a correct integration. This guide explains the Apideck unified accounting data model, how entities reference each other, and how data flows through the system.

---

## Entity Relationship Overview

The Apideck Accounting API models the core entities found across all major accounting systems. Here's how they connect:

```
Company
├── Ledger Accounts (chart of accounts)
├── Customers
├── Suppliers
├── Tax Rates
├── Tracking Categories
│
├── Accounts Receivable (AR)
│   ├── Invoices → line items ref accounts
│   │   ├── Payments (via allocations)
│   │   └── Credit Notes (refunds)
│   └── Aged Debtors (aging analysis)
│
├── Accounts Payable (AP)
│   ├── Bills → line items ref accounts
│   │   └── Bill Payments (via allocations)
│   ├── Expenses (already-paid transactions)
│   ├── Purchase Orders
│   └── Aged Creditors (aging analysis)
│
├── General Ledger
│   ├── Journals (groupings/books)
│   └── Journal Entries (debit/credit pairs)
│
├── Banking
│   ├── Bank Accounts
│   ├── Bank Feed Accounts
│   └── Bank Feed Statements
│
├── Financial Reporting
│   ├── Profit and Loss
│   └── Balance Sheet
│
└── Organization
    ├── Departments
    ├── Locations
    └── Subsidiaries
```

Every transaction entity (invoices, bills, expenses, journal entries) references **ledger accounts** via `account_id` on line items. Payments link to their parent transaction via **allocations**. Tax rates and tracking categories are applied at the line-item level.

---

## Core Entities

### Ledger Accounts (Chart of Accounts)

The **chart of accounts** is the foundation of every accounting system. All transactions ultimately reference ledger accounts.

| Field | Description |
|-------|-------------|
| `id` | Unique identifier |
| `nominal_code` | Account number/code (e.g., "6200") |
| `name` | Account name (e.g., "Travel Expenses") |
| `type` | Account type: `asset`, `liability`, `equity`, `revenue`, `expense`, `bank`, `other` |
| `sub_type` | More specific classification |
| `status` | `active` or `archived` |
| `currency` | Account currency |

**API**: [`GET /accounting/ledger-accounts`](/apis/accounting/reference#tag/Ledger-Accounts)

**Referenced by**: Invoices, Bills, Expenses, Journal Entries, Payments (as line item `account_id` or payment `account`)

---

### Invoices (Accounts Receivable)

Invoices represent money owed **to** your customer's business from their clients.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `customer_id` | Who owes the money | → **Customer** |
| `line_items[].account_id` | Revenue account for each line | → **Ledger Account** |
| `line_items[].tax_rate_id` | Tax rate applied | → **Tax Rate** |
| `line_items[].tracking_categories` | Categorization dimensions | → **Tracking Categories** |
| `ledger_account_id` | Default receivable account | → **Ledger Account** |

**API**: [`GET /accounting/invoices`](/apis/accounting/reference#tag/Invoices)

**Status flow**: `draft` → `authorised` → `paid` (status is computed based on payment allocations)

---

### Bills (Accounts Payable)

Bills represent money your customer's business owes **to** suppliers/vendors.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `supplier_id` | Who is owed the money | → **Supplier** |
| `line_items[].account_id` | Expense account for each line | → **Ledger Account** |
| `line_items[].tax_rate_id` | Tax rate applied | → **Tax Rate** |
| `line_items[].tracking_categories` | Categorization dimensions | → **Tracking Categories** |

**API**: [`GET /accounting/bills`](/apis/accounting/reference#tag/Bills)

**Status flow**: `draft` → `authorised` → `paid`

---

### Payments (Accounts Receivable)

Payments record money received against invoices.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `customer_id` | Who made the payment | → **Customer** |
| `account.id` | Bank account receiving payment | → **Ledger Account** (type: bank) |
| `allocations[].id` | Invoice being paid | → **Invoice** |
| `allocations[].amount` | Amount applied to that invoice | — |

**API**: [`GET /accounting/payments`](/apis/accounting/reference#tag/Payments)

**Key concept**: A single payment can be allocated across multiple invoices (partial payments and overpayments are handled via allocations).

---

### Bill Payments (Accounts Payable)

Bill payments record money paid against bills.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `supplier_id` | Who received the payment | → **Supplier** |
| `account.id` | Bank account used for payment | → **Ledger Account** (type: bank) |
| `allocations[].id` | Bill being paid | → **Bill** |
| `allocations[].amount` | Amount applied to that bill | — |

**API**: [`GET /accounting/bill-payments`](/apis/accounting/reference#tag/Bill-Payments)

---

### Expenses

Expenses represent purchases that are **already paid** (cash, credit card, or check transactions).

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `account_id` | Payment account (bank/card) | → **Ledger Account** (type: bank) |
| `supplier_id` | Merchant or vendor | → **Supplier** |
| `line_items[].account_id` | Expense category account | → **Ledger Account** (type: expense) |
| `line_items[].tax_rate_id` | Tax rate applied | → **Tax Rate** |
| `line_items[].tracking_categories` | Categorization dimensions | → **Tracking Categories** |

**API**: [`GET /accounting/expenses`](/apis/accounting/reference#tag/Expenses)

>
> Expenses are not supported by Exact Online. Use Bills instead, setting `due_date = bill_date` to indicate the transaction is already paid.

---

### Journal Entries

Journal entries are the most fundamental accounting record — every transaction in an accounting system ultimately creates journal entries with **debits** and **credits** that must balance.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `journal_id` | Parent journal/book | → **Journal** |
| `line_items[].account_id` | Account being debited or credited | → **Ledger Account** |
| `line_items[].type` | `debit` or `credit` | — |
| `line_items[].tracking_categories` | Categorization dimensions | → **Tracking Categories** |

**API**: [`GET /accounting/journal-entries`](/apis/accounting/reference#tag/Journal-Entries)

**Key rule**: Total debits must equal total credits in every journal entry.

---

### Journals

Journals are groupings or books that organize journal entries (e.g., "Sales Journal", "Purchase Journal", "General Journal").

| Field | Description |
|-------|-------------|
| `id` | Unique identifier |
| `name` | Journal name |

**Relationship**: Journals contain Journal Entries (`journal_entry.journal_id` → `journal.id`). Journals are referenced via the `journal_id` field on journal entries rather than through a separate API endpoint.

---

### Credit Notes

Credit notes represent refunds or adjustments against invoices (AR).

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `customer_id` | Customer receiving the credit | → **Customer** |
| `line_items[].account_id` | Account for the credit | → **Ledger Account** |
| `allocations[].id` | Invoice being credited | → **Invoice** |

**API**: [`GET /accounting/credit-notes`](/apis/accounting/reference#tag/Credit-Notes)

---

### Purchase Orders

Purchase orders represent approved requests to buy goods or services from suppliers. They precede bills in the procurement workflow.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `supplier_id` | Vendor fulfilling the order | → **Supplier** |
| `line_items[].account_id` | Expense account for each line | → **Ledger Account** |
| `line_items[].tax_rate_id` | Tax rate applied | → **Tax Rate** |

**API**: [`GET /accounting/purchase-orders`](/apis/accounting/reference#tag/Purchase-Orders)

---

## Banking

### Bank Accounts

Bank accounts represent the financial accounts held at banks or financial institutions.

| Field | Description | References |
|-------|-------------|------------|
| `id` | Unique identifier | — |
| `account_id` | Linked ledger account | → **Ledger Account** (type: bank) |
| `currency` | Account currency | — |
| `institution_name` | Bank name | — |

**API**: [`GET /accounting/bank-accounts`](/apis/accounting/reference#tag/Bank-Accounts)

### Bank Feed Accounts & Statements

Bank feeds enable automatic import of bank transactions into the accounting system. Bank feed accounts represent connected bank accounts, and bank feed statements contain the individual transactions.

**APIs**: [`GET /accounting/bank-feed-accounts`](/apis/accounting/reference#tag/Bank-Feed-Accounts) | [`GET /accounting/bank-feed-statements`](/apis/accounting/reference#tag/Bank-Feed-Statements)

See the [Xero Bank Feeds guide](/guides/bank-feeds-xero) for a detailed implementation walkthrough.

---

## Financial Reporting

### Profit and Loss

The profit and loss (P&L) statement summarizes revenues, costs, and expenses over a period — showing whether the business made a profit or loss.

**API**: [`GET /accounting/profit-and-loss`](/apis/accounting/reference#tag/Profit-and-Loss)

### Balance Sheet

The balance sheet provides a snapshot of assets, liabilities, and equity at a specific point in time.

**API**: [`GET /accounting/balance-sheet`](/apis/accounting/reference#tag/Balance-Sheet)

### Aged Debtors & Aged Creditors

Aging reports show outstanding AR (debtors) and AP (creditors) broken down by how long they've been outstanding — essential for cash flow management.

**APIs**: [`GET /accounting/aged-debtors`](/apis/accounting/reference#tag/Aged-Debtors) | [`GET /accounting/aged-creditors`](/apis/accounting/reference#tag/Aged-Creditors)

---

## Supporting Entities

| Entity | Purpose | API |
|--------|---------|-----|
| **Customers** | Counterparties for AR (invoices, payments) | [`GET /accounting/customers`](/apis/accounting/reference#tag/Customers) |
| **Suppliers** | Counterparties for AP (bills, bill payments, expenses) | [`GET /accounting/suppliers`](/apis/accounting/reference#tag/Suppliers) |
| **Tax Rates** | VAT/GST rates applied to line items | [`GET /accounting/tax-rates`](/apis/accounting/reference#tag/Tax-Rates) |
| **Tracking Categories** | Dimensions like departments, projects, locations | [`GET /accounting/tracking-categories`](/apis/accounting/reference#tag/Tracking-Categories) |
| **Departments** | Organizational departments for categorization | [`GET /accounting/departments`](/apis/accounting/reference#tag/Departments) |
| **Locations** | Business locations for multi-site tracking | [`GET /accounting/locations`](/apis/accounting/reference#tag/Locations) |
| **Subsidiaries** | Legal entities within a multi-company setup | [`GET /accounting/subsidiaries`](/apis/accounting/reference#tag/Subsidiaries) |
| **Attachments** | Receipts and documents linked to transactions | [`POST /accounting/attachments`](/apis/accounting/reference#tag/Attachments) |
| **Invoice Items** | Product/service catalog items for invoices | [`GET /accounting/invoice-items`](/apis/accounting/reference#tag/Invoice-Items) |

---

## Common Workflows

### Expense Reconciliation Flow

This is the most common workflow for expense management platforms:

```
1. Create Bill ──────────────────────┐
   POST /accounting/bills            │
   (references: supplier_id,         │
    line_items[].account_id,         │ Returns bill.id
    line_items[].tax_rate_id)        │
                                     │
2. Create Bill Payment ◀─────────────┘
   POST /accounting/bill-payments
   (references: account.id = bank account,
    allocations[].id = bill.id,
    allocations[].amount)

   → Bill status automatically updates to "paid"
```

### Invoice Payment Flow

```
1. Create Invoice ───────────────────┐
   POST /accounting/invoices         │
   (references: customer_id,         │ Returns invoice.id
    line_items[].account_id)         │
                                     │
2. Create Payment ◀──────────────────┘
   POST /accounting/payments
   (references: account.id = bank account,
    allocations[].id = invoice.id,
    allocations[].amount)

   → Invoice status automatically updates to "paid"
```

### Direct Journal Entry Flow

For advanced use cases where you need full control over debits and credits:

```
POST /accounting/journal-entries
{
  "journal_id": "purchase-journal",
  "line_items": [
    { "account_id": "6200", "type": "debit",  "total_amount": 100.00 },
    { "account_id": "1000", "type": "credit", "total_amount": 100.00 }
  ]
}
```

---

## How Entities Map Across Providers

| Apideck Entity | QuickBooks | Xero | Exact Online | NetSuite |
|----------------|-----------|------|--------------|----------|
| Ledger Account | Account | Account | GLAccount | Account |
| Invoice | Invoice | Invoice | SalesEntry | Invoice |
| Bill | Bill | Bill | PurchaseEntry | Vendor Bill |
| Credit Note | Credit Memo | Credit Note | — | Credit Memo |
| Payment | Payment | Payment | ReceivablesList | Customer Payment |
| Bill Payment | Bill Payment | Payment (AP) | PayablesList | Vendor Payment |
| Expense | Purchase | Bank Transaction | ❌ (use Bill) | Expense Report |
| Purchase Order | Purchase Order | Purchase Order | PurchaseOrder | Purchase Order |
| Journal Entry | Journal Entry | Manual Journal | General Journal Entry | Journal Entry |
| Customer | Customer | Contact (customer) | Account (customer) | Customer |
| Supplier | Vendor | Contact (supplier) | Account (supplier) | Vendor |
| Profit and Loss | Profit and Loss | Profit and Loss | — | Income Statement |
| Balance Sheet | Balance Sheet | Balance Sheet | — | Balance Sheet |

---

## ID References in API Responses

Every entity includes IDs that reference related entities. Here's how to follow the chain:

```javascript
// Fetch a bill
const bill = await apideck.accounting.billsOne({ id: 'bill-123' })

// Follow references
const supplier = await apideck.accounting.suppliersOne({
  id: bill.data.supplier_id
})

// Get account details for each line item
for (const item of bill.data.line_items) {
  const account = await apideck.accounting.ledgerAccountsOne({
    id: item.account_id
  })
  console.log(`${item.description}: ${account.data.name} (${account.data.nominal_code})`)
}

// Find payments for this bill
const billPayments = await apideck.accounting.billPaymentsAll()
const paymentsForBill = billPayments.data.filter((p) =>
  p.allocations?.some((a) => a.id === 'bill-123')
)
```

---

## Related Resources

- [Integrating Expenses and Bills](/guides/expenses-bills) — Step-by-step expense integration
- [Mark Invoices as Paid](/guides/mark-invoices-as-paid) — Payment allocation guide
- [Ledger Account Mapping](/guides/ledger-account-mapping) — Building a mapping UI
- [Journal Entries with Business Central](/guides/journal-entries-expenses-mbc) — MBC-specific journal entries
- [Journal Entries with Workday](/guides/journal-entries-expenses-ledger-accounts-workday) — Workday-specific guide
- [Tracking Dimensions](/guides/locations-subsidiaries-departments) — Departments, locations, subsidiaries
- [Accounting API Reference](/apis/accounting/reference) — Full API documentation
