Multi-Company Support in Accounting Integrations
Introduction
Many accounting platforms allow users to manage multiple companies, tenants, or entities within a single account. Apideck's Accounting API supports switching between these companies at request time using the x-apideck-company-id header, eliminating the need for separate connections per company.
How It Works
When a consumer connects their accounting platform through Vault, they select a default company. This default is used for all API requests unless you explicitly override it using the x-apideck-company-id header.
The x-apideck-company-id Header
Include this optional header in your Unified API requests to route the request to a specific company:
When the header is:
- Provided: The request is routed to the specified company
- Omitted: The request uses the default company configured during connection setup
Supported Connectors
The following accounting connectors support multi-company at request time:
| Connector | Company Concept | Notes |
|---|---|---|
| Xero | Tenant | One OAuth connection accesses all tenants |
| Sage Business Cloud | Business | Multiple businesses per account |
| Sage Intacct | Entity | Multi-entity support within organization |
| Microsoft Dynamics 365 BC | Company | Multiple companies per environment |
| Exact Online | Division | Multiple divisions per account |
Note
Connectors like QuickBooks Online, Zoho Books, and FreshBooks require one OAuth authorization per company. For these, you'll need to create separate connections for each company.
Listing Available Companies
To retrieve the list of companies available for a connection, use the Companies endpoint:
Response:
Use the id value as the x-apideck-company-id header value in subsequent requests.
Note
The Companies endpoint is only available for connectors that support multi-company. Calling it on unsupported connectors will return an error.
Identifying the Active Company via Metadata
Each connection exposes a standardized metadata.company_id field that reflects which company the connection is currently scoped to. This value is automatically synced whenever the company setting changes — whether through the Vault UI, the API, or after an OAuth authorization flow.
Why This Matters
Multi-company connectors each use a different internal setting for company selection (e.g., Xero uses tenant_id, Sage Business Cloud uses business_id, Dynamics 365 BC uses company_id). Instead of having to know the connector-specific key, you can always read metadata.company_id for a consistent, connector-agnostic reference.
Reading metadata.company_id
The field is available on the connection object returned by the Vault API:
The response includes the metadata:
When It Syncs
metadata.company_id is updated automatically in these scenarios:
- Settings update: When a consumer changes the company selection via Vault or the API
- OAuth authorization: When a token-success hook auto-selects a company (e.g., Xero selecting the only available tenant)
Note
Existing connections won't have metadata.company_id until the next settings change or
re-authorization. There is no backfill — the field is populated going forward.
Connector Setting Key Mapping
For reference, here's which setting key maps to metadata.company_id for each connector:
| Connector | Setting Key |
|---|---|
| Xero | tenant_id |
| Sage Business Cloud | business_id |
| Sage Intacct | entity |
| Microsoft Dynamics 365 BC | company_id |
| Exact Online | systemDivisionId |
Common Use Cases
1. Multi-Tenant SaaS Applications
If your application serves users who manage multiple companies, you can let them switch between companies without re-authenticating:
2. Consolidated Reporting
Aggregate data across multiple companies by iterating through available companies:
3. Company Selector in Your UI
Let users select which company to work with:
Virtual Webhooks and Multi-Company
Virtual 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 to receive webhook events from multiple companies, you have two options:
- Create separate connections: Set up a connection per company, each with its own default company selection
- Use polling: Query the API directly with the
x-apideck-company-idheader to fetch data from specific companies on demand
Error Handling
Invalid Company ID
The x-apideck-company-id value is passed directly to the downstream API without validation. If you provide an invalid or inaccessible company ID, the error response will come from the downstream connector and vary depending on the service.
For example, Xero might return:
Always use the Companies endpoint to retrieve valid company IDs before making requests.