# Multi-entity accounting and tracking dimensions

This guide explains how Apideck's Accounting API handles **multiple companies or legal entities** and **tracking dimensions** (departments, locations, subsidiaries, and custom categories). Understanding both helps you build integrations that match how each accounting platform works.

For an in-depth look at how specific ERPs (NetSuite, Sage Intacct, Acumatica, etc.) structure entities, return GL data, and handle consolidation natively, see the [Multi-Entity ERP Behavior guide](/guides/multi-entity-erp-behavior).

---

## Two layers: data scope vs tagging

```text
┌─────────────────────────────────────────────────────────────────────┐
│                     YOUR APIDECK CONNECTION                        │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  LAYER 1 — Data boundary                                     │  │
│  │  "Whose books am I looking at?"                               │  │
│  │                                                               │  │
│  │  x-apideck-company-id: A  ──→  Company A's ledger, invoices  │  │
│  │  x-apideck-company-id: B  ──→  Company B's ledger, invoices  │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  LAYER 2 — Tracking dimensions                                │  │
│  │  "How is this transaction tagged for reporting?"              │  │
│  │                                                               │  │
│  │  Invoice #1001                                                │  │
│  │  ├── department_id: "sales"                                   │  │
│  │  ├── location_id: "london"                                    │  │
│  │  └── line_items:                                              │  │
│  │      ├── Line 1  tracking_categories: ["project-alpha"]       │  │
│  │      └── Line 2  tracking_categories: ["project-beta"]        │  │
│  └───────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘
```

### Layer 1 — Data boundary (which entity's books?)

This answers: *When I list ledger accounts, invoices, or journal entries, whose data am I seeing?*

For connectors that support **per-request company switching**, you choose the entity by sending the **`x-apideck-company-id`** HTTP header on Accounting API requests. The value is an identifier returned by **`GET /accounting/companies`** for that connection.

```text
One connection
  │
  ├── GET /accounting/companies  →  [Company A, Company B, Company C]
  │
  ├── GET /accounting/ledger-accounts
  │   Header: x-apideck-company-id: A
  │   └── Returns chart of accounts for Company A
  │
  └── GET /accounting/journal-entries
      Header: x-apideck-company-id: B
      └── Returns journal entries for Company B
```

If you omit the header, requests typically use the **default company** stored on the connection (for example, the organisation or entity chosen during setup or OAuth).

### Layer 2 — Tracking dimensions (how is this transaction segmented?)

This answers: *How should this invoice or line appear in management reporting—by department, location, legal entity tag, or custom category?*

Common fields on transaction **headers** and **line items**:

| Concept | API fields (typical) | Role |
|--------|----------------------|------|
| Department | `department_id` | Cost center / org unit |
| Location | `location_id` | Site, region, or logical place |
| Subsidiary | `subsidiary_id` | Legal entity tag on the transaction |
| Custom segments | `tracking_categories[]` | Classes, projects, grants—platform-dependent |

>
> For most connectors, department, location, and tracking categories are **tags** for reporting. They do not by themselves switch which company's **list** endpoints return.

**Subsidiary** is special: it often acts as a **dimension on the transaction**, and on some platforms it is tightly tied to **which legal entity** owns that transaction. It is still distinct from the **`x-apideck-company-id`** header, which controls **read scope** where that feature is supported.

### How the two layers work together

When both apply, you might **scope** reads to Company A with the header, while **line items** still carry their own `department_id`, `location_id`, or `tracking_categories`. **Line-level** dimension values usually override **header-level** values for that line—useful when one document splits costs across teams or projects.

```text
  Request: GET /accounting/invoices
  Header:  x-apideck-company-id: "company-a"        ← Layer 1: scope

  Response:
  ┌─────────────────────────────────────────────────┐
  │  Invoice #1001                                  │
  │  department_id: "marketing"      ← Layer 2      │
  │  location_id:   "new-york"       ← Layer 2      │
  │                                                 │
  │  Line items:                                    │
  │  ┌─────────────────────────────────────────┐    │
  │  │ Line 1: $500  dept: "marketing"         │    │
  │  │         tracking: ["project-alpha"]     │    │
  │  ├─────────────────────────────────────────┤    │
  │  │ Line 2: $300  dept: "engineering"       │    │  ← overrides
  │  │         tracking: ["project-beta"]      │    │    header dept
  │  └─────────────────────────────────────────┘    │
  └─────────────────────────────────────────────────┘
```

---

## Switching companies with `x-apideck-company-id`

### What to do

**Step 1** — List available companies:

```bash
curl -X GET "https://unify.apideck.com/accounting/companies" \
  -H "Authorization: Bearer {api-key}" \
  -H "x-apideck-app-id: {app-id}" \
  -H "x-apideck-consumer-id: {consumer-id}" \
  -H "x-apideck-service-id: xero"
```

```json
{
  "data": [
    { "id": "org-abc-123", "legal_name": "Acme US Inc." },
    { "id": "org-def-456", "legal_name": "Acme UK Ltd." },
    { "id": "org-ghi-789", "legal_name": "Acme EU GmbH" }
  ]
}
```

**Step 2** — Use a company ID on subsequent requests:

```bash
curl -X GET "https://unify.apideck.com/accounting/invoices" \
  -H "Authorization: Bearer {api-key}" \
  -H "x-apideck-app-id: {app-id}" \
  -H "x-apideck-consumer-id: {consumer-id}" \
  -H "x-apideck-service-id: xero" \
  -H "x-apideck-company-id: org-def-456"
```

This returns invoices for **Acme UK Ltd.** only. Same connection, same consumer—just a different company context.

>
> Connection metadata may also expose a default company identifier (for example in connection metadata after setup). The header overrides that default when the connector supports multi-company switching.

> **Virtual Webhooks limitation**
>
> [Virtual Webhooks](/guides/webhooks) currently only sync data from the **default company** configured during connection setup. The `x-apideck-company-id` header is not supported for webhook subscriptions. If you need events from multiple companies, either create **separate connections per company** or **poll** the API with the header on a schedule.

### Which pattern does your connector use?

```text
  Does your connector support
  x-apideck-company-id switching?
          │
    ┌─────┴─────┐
    ▼           ▼
   YES          NO
    │           │
    │     ┌─────┴──────────────┐
    │     ▼                    ▼
    │   SMB / single-entity   Enterprise / ERP
    │     │                    │
    │     │                    ├── Check if subsidiary_id
    │     │                    │   is required on writes
    │     │                    │
    │     │                    └── Filter list responses
    │     │                        by subsidiary_id
    │     │
    │     └── Create one Vault
    │         connection per company
    │
    └── Use x-apideck-company-id
        header to switch at request time
```

### Connectors that support per-request company switching

| Connector | What "company" represents | Downstream mechanism |
|-----------|---------------------------|----------------------|
| **Xero** | Organisation | `Xero-Tenant-Id` header |
| **Sage Intacct** | Entity | Session follows selected entity |
| **Sage Business Cloud** | Business | Business context switch |
| **Dynamics 365 BC** | Company | Company in URL path |
| **Exact Online** | Division | Division-based routing |

> **Exact Online variants**
>
> Choose the `service_id` that matches your product—**`exact-online`**, **`exact-online-nl`**, or **`exact-online-uk`**. All three use the same **division-based** pattern for `GET /accounting/companies` and **`x-apideck-company-id`**.

Always confirm current behavior in the [Apideck Accounting API reference](https://developers.apideck.com/apis/accounting) for your connector; capabilities evolve.

### Connectors that need one connection per company

```text
  ┌──────────────────┐     ┌──────────────────┐
  │  Connection 1    │     │  Connection 2    │
  │  QuickBooks      │     │  QuickBooks      │
  │  Realm: Acme US  │     │  Realm: Acme UK  │
  │                  │     │                  │
  │  GET /invoices   │     │  GET /invoices   │
  │  → US invoices   │     │  → UK invoices   │
  └──────────────────┘     └──────────────────┘
```

Some integrations bind one OAuth token (or one company) to a single legal entity. In those cases **`x-apideck-company-id` does not switch companies**—you create **one connection per company**.

- **QuickBooks Online** — One company per connection (realm)
- **MYOB** — One company per connection

### Other connectors (not in the header-switching table)

Many other accounting `service_id` values follow different rules:

| Pattern | What to expect | Examples |
|--------|----------------|----------|
| **One ledger per connection** | Use **another Vault connection** for another company | FreshBooks, Zoho Books, KashFlow, FreeAgent, Banqup, Visma Netvisor, Procountor, Access Financials |
| **Entity on records** | Entity may appear on **payloads** or **query parameters** | Campfire, Dualentry |
| **Rich dimensions, scoped connection** | One company per connection; branches are **dimensions on records** (all branches returned together — filter by `BranchID`) | Acumatica, MYOB-Acumatica |
| **Enterprise dimensions** | `company_id` / `subsidiary_id` / worktags carry entity meaning | Intuit Enterprise Suite, Workday |

For any connector, confirm **multi-company flags**, **required fields**, and **resource coverage** in the [Accounting API reference](https://developers.apideck.com/apis/accounting) and the connector's page on [developers.apideck.com/connectors](https://developers.apideck.com/connectors).

### Xero: multiple organisations vs app partnership

These are two separate ideas:

```text
  ┌─────────────────────────────────────────────────────────────┐
  │  1. Multi-org switching (per connection)                    │
  │                                                             │
  │  User authorises your app via OAuth                         │
  │  └── Grants access to Org A, Org B, Org C                  │
  │      └── GET /accounting/companies → lists all three        │
  │          └── x-apideck-company-id selects which one         │
  │                                                             │
  │  This is normal Xero OAuth. No special tier needed.         │
  └─────────────────────────────────────────────────────────────┘

  ┌─────────────────────────────────────────────────────────────┐
  │  2. App connection limits (across all your customers)       │
  │                                                             │
  │  Xero limits how many active connections your app can have  │
  │  └── To raise/remove limits: Xero App Partner certification │
  │                                                             │
  │  This is about scaling, not about switching orgs.           │
  └─────────────────────────────────────────────────────────────┘
```

If you are scaling to **many end-customer connections**, plan for Xero's commercial and certification requirements **in addition to** multi-org switching. See Xero's [App Partner program](https://developer.xero.com/documentation/xero-app-store/app-partner-guides/app-partner-steps/), Apideck's [Xero connector documentation](https://developers.apideck.com/connectors/xero), and [Xero API pricing and the App Partner Program](https://www.apideck.com/blog/xero-api-pricing-and-the-app-partner-program).

### Does the parent GL include subsidiaries? (Roll-up behavior)

A common question when integrating with multi-entity ERPs: **when I read GL data at the parent level, do I get a roll-up of all subsidiaries, or just the parent's own ledger?**

This depends entirely on how the downstream ERP returns data. Apideck does not aggregate or consolidate — it returns what the ERP gives.

```text
  ┌─────────────────────────────────────────────────────────────────────┐
  │  ROLL-UP BY DEFAULT                                                 │
  │  GL list endpoints return data across all entities in one response  │
  │  Your app must filter by subsidiary/entity field                    │
  │                                                                     │
  │  ● NetSuite OneWorld — all subsidiaries in one response             │
  │    Filter by: subsidiary_id on each record                          │
  │                                                                     │
  │  ● Workday — all companies returned by default                      │
  │    Filter by: company_id on each record                             │
  │                                                                     │
  │  ● Acumatica — all branches within a company returned together      │
  │    Filter by: BranchID on each record                               │
  ├─────────────────────────────────────────────────────────────────────┤
  │  ISOLATED PER ENTITY                                                │
  │  Each API call returns data for exactly one company/entity          │
  │  Use x-apideck-company-id or separate connections to switch         │
  │                                                                     │
  │  ● Sage Intacct — entity-scoped sessions via x-apideck-company-id   │
  │  ● Dynamics 365 BC — company ID required in URL path                │
  │  ● Xero — tenant ID required per request (no cross-org query)       │
  │  ● QuickBooks Online — one realm per connection                     │
  │  ● Exact Online — one division per API call                         │
  │  ● Intuit Enterprise Suite — per-entity connection                  │
  │  ● MYOB — one company per connection                                │
  └─────────────────────────────────────────────────────────────────────┘
```

**What this means for your integration:**

| If the ERP... | Then to show one entity's GL... | And to show a consolidated GL... |
|---------------|--------------------------------|----------------------------------|
| **Rolls up** (NetSuite, Workday) | Filter the response by `subsidiary_id` or equivalent | Use the full response, then eliminate intercompany + convert currencies |
| **Rolls up branches, isolates companies** (Acumatica) | Filter by `BranchID`; separate connections for separate companies | Within a company: use the full response. Across companies: iterate connections and merge |
| **Isolates** (Xero, QBO, Exact, Dynamics BC, Sage Intacct) | Just read — the response is already scoped | Iterate all entities, merge, eliminate intercompany + convert currencies |

>
> For details on how each ERP structures entities internally, what the "parent" GL actually contains, and how native consolidation works, see the [Multi-Entity ERP Behavior guide](/guides/multi-entity-erp-behavior).

---

## Tracking dimensions — quick reference

### Master data endpoints

```text
  /accounting/departments          → Cost centers, org units
  /accounting/locations            → Sites, regions
  /accounting/subsidiaries         → Legal entities
  /accounting/tracking-categories  → Classes, projects, custom tags
```

### Where dimensions appear on transactions

```text
  POST /accounting/invoices
  ┌──────────────────────────────────────────────────────────┐
  │  Header-level dimensions (apply to entire document)      │
  │  ┌────────────────────────────────────────────────────┐  │
  │  │  department_id:        "dept-marketing"            │  │
  │  │  location_id:          "loc-london"                │  │
  │  │  tracking_categories:  [{ id: "cat-q1" }]         │  │
  │  └────────────────────────────────────────────────────┘  │
  │                                                          │
  │  Line items (can override header values per line)        │
  │  ┌────────────────────────────────────────────────────┐  │
  │  │  Line 1: $2,000                                   │  │
  │  │    department_id: "dept-marketing"     (inherited) │  │
  │  │    subsidiary_id: "sub-us-corp"                    │  │
  │  │    tracking_categories: [{ id: "cat-q1" }]        │  │
  │  ├────────────────────────────────────────────────────┤  │
  │  │  Line 2: $800                                     │  │
  │  │    department_id: "dept-engineering"   (override!) │  │
  │  │    subsidiary_id: "sub-uk-ltd"                     │  │
  │  │    tracking_categories: [{ id: "cat-q2" }]        │  │
  │  └────────────────────────────────────────────────────┘  │
  └──────────────────────────────────────────────────────────┘
```

Support varies by resource and by connector. At the unified API level, several resources accept `department_id`, `location_id`, `subsidiary_id`, and/or `tracking_categories` on the **header** and/or **line items**—not always all four on every resource.

**Typical patterns by resource:**

| Resource | Header dimensions | Line-item dimensions |
|----------|-------------------|----------------------|
| **Invoices & bills** | department, location, tracking categories | All four including subsidiary |
| **Journal entries** | Varies | Primarily on lines |
| **Credit notes** | department, location | Often fewer subsidiary fields than invoices |

Refer to the request body schema for each operation in the [API reference](https://developers.apideck.com/apis/accounting) for the exact combination.

### How popular platforms map to unified fields

```text
  Unified API field        QuickBooks    Xero          NetSuite      Sage Intacct    Workday
  ─────────────────────    ──────────    ────          ────────      ────────────    ───────
  department_id        →   Department    Tracking Cat  Department    Department      Worktag
  location_id          →   Location      Tracking Cat  Location      Location        Worktag
  subsidiary_id        →   N/A ¹         N/A           Subsidiary    Entity          Company
  tracking_categories  →   Class         Tracking Cat  Class/Seg     Custom dims     Worktag
                                         (up to 2)

  ¹ QuickBooks: use one connection per company instead
```

>
> Xero has **no separate** department/location/subsidiary resources. Many customers use their **two tracking categories** to represent "department" and "region." **Workday** uses worktags for most dimensions—`company_id` and `subsidiary_id` behave differently there.

### `company_id` vs `subsidiary_id` on transaction records

The unified API exposes both **`company_id`** and **`subsidiary_id`** in places, but connectors treat them differently:

```text
  ┌─────────────┬──────────────────────────────────────────────────┐
  │  NetSuite   │  company_id and subsidiary_id often hold the     │
  │             │  SAME value (duplicated). But on Checks they     │
  │             │  can differ. On some resources only company_id   │
  │             │  is populated.                                   │
  ├─────────────┼──────────────────────────────────────────────────┤
  │  Workday    │  DIFFERENT meanings — company vs intercompany    │
  │             │  affiliate. Never treat them as interchangeable. │
  ├─────────────┼──────────────────────────────────────────────────┤
  │  QuickBooks │  Company scope is the connection itself,         │
  │  Xero       │  not body fields. Neither field typically        │
  │  Exact, etc │  appears on transaction payloads.                │
  ├─────────────┼──────────────────────────────────────────────────┤
  │  Sage       │  company_id in connection settings is for        │
  │  Intacct    │  auth/session — not entity tagging.              │
  │             │  location_id can overlap with entity concept.    │
  └─────────────┴──────────────────────────────────────────────────┘
```

>
> For **legal-entity tagging on create/update**, prefer **`subsidiary_id`** unless documentation for your connector explicitly requires **`company_id`**.

---

## Frequently asked questions

### How do I read GL data for one specific entity?

```text
  Does the connector support x-apideck-company-id?
          │
    ┌─────┴─────┐
    ▼           ▼
   YES          NO
    │           │
    │     Is it NetSuite?
    │       │         │
    │      YES        NO
    │       │         │
    │       │         └── Create one Vault connection
    │       │             per company
    │       │
    │       └── List all, then filter
    │           by subsidiary_id in your app
    │
    └── 1. GET /accounting/companies
        2. Set x-apideck-company-id header
        3. Call ledger-accounts, invoices, etc.
```

### What is the difference between `x-apideck-company-id` and `subsidiary_id`?

```text
  x-apideck-company-id (HTTP header)
  └── "For this REQUEST, scope data to this company"
      └── Controls which company's data the API returns
          └── Set once per request

  subsidiary_id (field on record/line)
  └── "This RECORD or LINE belongs to this entity"
      └── Used for posting and reporting
          └── Can vary per line item
```

They may align for a given document (same entity everywhere) or differ in advanced cases (for example intercompany entries where lines reference different entities).

### Should I use `company_id` or `subsidiary_id` on create/update payloads?

Prefer **`subsidiary_id`** for legal-entity tagging on transactions.

| Connector | Recommendation |
|-----------|----------------|
| **NetSuite** | `company_id` often mirrors `subsidiary_id` (same value). Pick one consistent field after checking the response shape per resource. |
| **Workday** | **Not interchangeable** — use what the resource schema specifies. |
| **Others** | `company_id` is easily confused with connection settings or the header. Default to `subsidiary_id`. |

### How do I consolidate GL data across entities for one customer?

```text
  1. Discover    List all connections for the consumer
                 + GET /accounting/companies per connection
                 = full list of entities
                      │
  2. Extract     For each entity, read ledger-accounts,
                 journal-entries, invoices, bills
                 (using header or separate connection)
                      │
  3. Normalise   Map each entity's chart of accounts
                 to your consolidated account structure
                      │
  4. Convert     Apply exchange rates for multi-currency
                      │
  5. Eliminate   Remove intercompany balances
                      │
  6. Aggregate   Sum into consolidated P&L / balance sheet
```

This is application-level logic — Apideck provides the per-entity data, your platform handles mapping, conversion, and elimination.

### Can one API call represent multiple legal entities?

That is **intercompany** or **cross-entity** posting. It is only possible where the downstream system allows it. **NetSuite** and **Workday** are common examples; many SMB-oriented systems isolate entities per connection or per organisation.

---

## Consolidating GL data across entities

A common use case is reading GL data from **multiple legal entities** and merging it into a **single view** — for consolidated reporting, intercompany elimination, or multi-entity dashboards. This section explains how entity data maps to Apideck's consumer model and what to consider when designing consolidation logic.

### How entities map to consumers and connections

In Apideck, a **consumer** represents your customer. One consumer can have **multiple connections**, and some connections give access to **multiple companies**. Understanding this hierarchy is key to consolidation:

```text
  Your customer (consumer-id: "acme-corp")
  │
  ├── Connection 1: Xero
  │   └── x-apideck-company-id switches between:
  │       ├── "org-us"   → Acme US Inc.     (chart of accounts, invoices, GL)
  │       ├── "org-uk"   → Acme UK Ltd.     (chart of accounts, invoices, GL)
  │       └── "org-eu"   → Acme EU GmbH     (chart of accounts, invoices, GL)
  │
  ├── Connection 2: QuickBooks (Acme AU)
  │   └── Single company per connection      (chart of accounts, invoices, GL)
  │
  └── Connection 3: QuickBooks (Acme NZ)
      └── Single company per connection      (chart of accounts, invoices, GL)
```

All five entities belong to **one consumer** (`acme-corp`). To build a consolidated view you need to iterate across all of them — some via the header, some via separate connections.

### Reading GL data across all entities

```text
  ┌──────────────────────────────────────────────────────────────────┐
  │  Step 1: Discover all entities for this consumer                │
  │                                                                  │
  │  For each connection:                                            │
  │  ├── GET /accounting/companies                                   │
  │  │   └── Returns list of switchable companies (if supported)     │
  │  │                                                               │
  │  └── If only one company (or endpoint not supported):            │
  │      └── The connection itself = one entity                      │
  ├──────────────────────────────────────────────────────────────────┤
  │  Step 2: Read GL data per entity                                 │
  │                                                                  │
  │  For each entity:                                                │
  │  ├── GET /accounting/ledger-accounts  (chart of accounts)        │
  │  ├── GET /accounting/journal-entries  (GL transactions)          │
  │  ├── GET /accounting/invoices         (AR)                       │
  │  ├── GET /accounting/bills            (AP)                       │
  │  └── GET /accounting/profit-and-loss  (reports, where available) │
  │                                                                  │
  │  Set x-apideck-company-id when the connection supports it.       │
  │  Use a separate connection when it does not.                     │
  ├──────────────────────────────────────────────────────────────────┤
  │  Step 3: Merge in your application                               │
  │                                                                  │
  │  Tag each record with its source entity, then consolidate:       │
  │  ├── Map charts of accounts (may differ per entity)              │
  │  ├── Convert currencies to reporting currency                    │
  │  ├── Eliminate intercompany balances                              │
  │  └── Aggregate into consolidated view                            │
  └──────────────────────────────────────────────────────────────────┘
```

### Example: iterating entities for one consumer

**Header-switching connector (e.g. Xero):**

```bash
# 1. List companies on the connection
curl -X GET "https://unify.apideck.com/accounting/companies" \
  -H "Authorization: Bearer {api-key}" \
  -H "x-apideck-app-id: {app-id}" \
  -H "x-apideck-consumer-id: acme-corp" \
  -H "x-apideck-service-id: xero"

# 2. For each company, read ledger accounts
curl -X GET "https://unify.apideck.com/accounting/ledger-accounts" \
  -H "Authorization: Bearer {api-key}" \
  -H "x-apideck-app-id: {app-id}" \
  -H "x-apideck-consumer-id: acme-corp" \
  -H "x-apideck-service-id: xero" \
  -H "x-apideck-company-id: org-us"

# Repeat for org-uk, org-eu...
```

**Connection-per-company connector (e.g. QuickBooks):**

```bash
# Each connection is a separate company — no company header needed
curl -X GET "https://unify.apideck.com/accounting/ledger-accounts" \
  -H "Authorization: Bearer {api-key}" \
  -H "x-apideck-app-id: {app-id}" \
  -H "x-apideck-consumer-id: acme-corp" \
  -H "x-apideck-service-id: quickbooks"
  # This returns data for whichever QuickBooks realm is on this connection
```

### Key considerations for consolidation

#### Charts of accounts differ per entity

Each legal entity may have its own chart of accounts with different account numbers, names, and structures. Your consolidation logic needs a **mapping layer**:

```text
  Entity: Acme US          Entity: Acme UK          Your consolidated
  ┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
  │ 4000 Revenue     │────→│ 200 Sales Income │────→│ Revenue          │
  │ 5000 COGS        │────→│ 300 Cost of Sale │────→│ Cost of Goods    │
  │ 6100 Rent        │────→│ 400 Premises     │────→│ Operating Exp.   │
  └──────────────────┘     └──────────────────┘     └──────────────────┘
```

See the [Ledger Account Mapping guide](/guides/ledger-account-mapping) for how to build a mapping interface.

>
> Some ERPs share the chart of accounts across all entities (Sage Intacct, Acumatica within a tenant), making consolidation simpler — no mapping needed. See the [ERP Behavior guide](/guides/multi-entity-erp-behavior) for specifics.

#### Currency handling

Multi-entity setups often span currencies. The Accounting API returns amounts in each entity's **base currency**. Your consolidation must:

1. Identify each entity's base currency (from company or ledger account metadata)
2. Apply exchange rates to convert to your reporting currency
3. Handle exchange rate differences as a separate consolidation line

#### Intercompany elimination

When entities transact with each other (e.g. Acme US invoices Acme UK), those balances appear in both entities' books. For a true consolidated view, you need to:

- Identify intercompany transactions (by counterparty, tracking category, or a naming convention)
- Eliminate matching receivables/payables so they do not double-count

>
> Apideck does not perform consolidation, currency conversion, or intercompany elimination — these are application-level responsibilities. The API provides the per-entity data you need to build these workflows.

---

## Current limitations (good to plan for)

- **NetSuite** — List endpoints may aggregate across subsidiaries; do not assume header-based scoping behaves like Xero or Sage Intacct. `company_id` / `subsidiary_id` duplication varies by resource.
- **`company_id` vs `subsidiary_id`** — Redundant same-value pairs are **primarily a NetSuite quirk**. Workday intentionally uses both fields differently. Most SMB connectors scope company via connection or headers, not both body fields.
- **Sage Intacct** — Each entity is isolated; the top-level entity is **not** a consolidated roll-up. `company_id` in settings is for auth/session, not dimension tagging.
- **Acumatica** — Branches share one GL (roll-up), but separate companies are isolated. All companies within a tenant share the same COA and base currency.
- **Connector matrix** — Not every connector exposes all four dimension types or CRUD for every dimension resource; always check the connector's Accounting coverage.
- **Connectors omitted from examples** — Regional variants, niche ERPs, and new connectors may differ; treat the [API reference](https://developers.apideck.com/apis/accounting) as the source of truth when this guide does not name your `service_id`.

---

## Related resources

- [Apideck Accounting API](https://developers.apideck.com/apis/accounting)
- [Multi-Entity ERP Behavior](/guides/multi-entity-erp-behavior) — deep dive into how each ERP structures entities, returns GL data, and handles consolidation
- [Tracking dimensions in accounting integrations](https://www.apideck.com/blog/tracking-dimensions-in-accounting-integrations) (blog)

If you need a connector-specific implementation checklist (auth, required fields, sandbox), use Apideck's connection and connector guides for that service in the developer portal.
