Skip to main content
Pleo caps a company at 11,000 active Accounts (Chart of Accounts entries). Some Accounting Systems maintain a full chart of accounts with tens of thousands of entries. Only a small fraction of these are ever relevant to Pleo, but syncing the full set can exceed the limit. This how-to explains how to handle that limit in your integration.

When to Use This

This how-to is useful when your integration is at risk of syncing more than 11,000 active Accounts to Pleo.

Prerequisites

Before you begin:

Steps

1. Filter to Expense-Relevant Accounts

Before fetching or matching anything, filter the AS chart of accounts to the accounts relevant for expense categorisation in Pleo. This is typically expense-type and P&L (profit and loss) accounts. Asset, liability, equity, and bank accounts are generally not needed, so exclude them. This step runs entirely on data already available from the AS. It does not call the Pleo API. Example Pseudo:
The exact field used to classify accounts depends on what the AS exposes. If the AS does not expose an account type, fall back to the AS’s own chart of accounts numbering convention (for example, a defined range of account codes for expense accounts).

2. Check the Filtered Count Against the Limit

filtered_as_accounts, built in step 1, is what you want Pleo to have as active Accounts once the sync finishes. Check its size against the 11,000 limit before making any Pleo API calls. Example Pseudo:
You can do this check using only filtered_as_accounts, without looking at Pleo’s current Accounts at all, because Chart of Accounts Sync is a full reconciliation. By the end of a run, Pleo’s active Accounts always match filtered_as_accounts exactly:
  • An account in filtered_as_accounts that’s already active in Pleo: no change.
  • An account in filtered_as_accounts that’s missing, or archived, in Pleo: created or unarchived.
  • An account active in Pleo but not in filtered_as_accounts: archived.
For example: Pleo has 10,000 active Accounts today, and filtered_as_accounts has 9,500: Archive the 1,500 first, then create or unarchive the 1,000. After the sync, Pleo has 9,500 active Accounts (8,500 + 1,000), matching filtered_as_accounts exactly.

3. Archive Accounts No Longer in the Filtered Set First

Archive Accounts in this step. Account creation and unarchiving happen in the next step. Pleo never lets a company go over 11,000 active Accounts, and it checks the limit on both create and unarchive requests. If the company is close to the limit, a create or unarchive request sent before the archive step can be rejected with an HTTP 400, even though the sync would end up within the limit. Fetch Pleo’s current Chart of Accounts, including archived Accounts, the same way as How to Sync Accounts, then follow How to Create, Update, and Archive Accounts for the archive API request itself. The difference from that how-to is that you match against filtered_as_accounts, not all_as_accounts (the unfiltered list from step 1). Accounts excluded by filtering, for example asset or liability accounts, get archived here if they were previously synced as active. This step catches them on every sync run, so they don’t stay active in Pleo after they drop out of the filtered set. Example Pseudo:

4. Create or Unarchive the Remaining Accounts

Once the archive step has run, create the Accounts in filtered_as_accounts that are missing in Pleo, and unarchive the ones that were already archived in Pleo but that the sync now needs active.

5. Handle a Rejection from Pleo

If a sync skips the step 2 pre-check, Pleo doesn’t reject the whole sync at once. No single request can contain more than 1,000 Accounts (see How to Create Multiple Accounts in a Single Request). Instead, once the company’s active Accounts reach 11,000, further create calls (sent individually or as part of a batch) and further unarchive calls (always sent individually) get rejected outright with a top-level HTTP 400:
A batch can still fail per-item for unrelated reasons, for example EXTERNAL_ID_ALREADY_EXISTS (see Handling Failures), even when it isn’t hitting the active Account limit. Check both error shapes in your response handling: a top-level 400 for exceeding the limit, and the per-item failed array for everything else. Example Pseudo:
The same 400 can happen on a single unarchive call too, since unarchive is always sent individually via How to Create, Update, and Archive Accounts. Check response.status on that call the same way.

Error Codes