Skip to main content
This page describes the Vendor Sync reconciliation process: synchronising active vendors from the Accounting System with Vendors in Pleo. This step runs on every Vendor Sync cycle.

Implementation

For a conceptual overview of how AS vendors map to Pleo Vendors, see Platform Capabilities: Vendor Sync.

Matching Rules

  • Matching is performed using the externalId field on both ends.
  • The externalId is the unique, long-lasting identifier assigned to the vendor by the Accounting System.
  • code and name are not used for matching, only externalId is used.

Invalid or Duplicate externalId

Since matching relies entirely on externalId, treat it as a hard requirement. If the AS returns a vendor with an empty or null externalId, skip that vendor and log an error: do not create or update a Pleo Vendor for it. Duplicates are a data integrity error, not a matching decision. If the AS returns two or more vendors with the same externalId, skip all of them and log an error rather than arbitrarily matching one; the AS may not enforce uniqueness on externalId, so this can happen on any sync run. Pleo enforces externalId uniqueness per company at the database level, so Pleo-side duplicates shouldn’t normally occur, but the integration should still defend against one when matching (see How to Fetch and Match Vendors), in case of legacy data or any other data-quality issue.

Partial Fetch Failures

Fetches must be complete before reconciliation begins. If any page fetch fails, whether from the Accounting System or from Pleo, abort the entire sync run without performing any create, update, unarchive, or archive operation. Do not reconcile using a partial result set: this can incorrectly archive vendors that were never fetched due to the error. Retry the full fetch on the next sync cycle.

Sync Process

1. Fetch Active Vendors from the AS

Retrieve all active vendors from the Accounting System. Only active vendors are used for reconciliation. Inactive, blocked, or deleted vendors in the AS are not synced into Pleo.

2. Fetch Vendors from Pleo

Retrieve both active and archived Vendors from Pleo for the connected company. Including archived Vendors allows unarchiving rather than creating duplicates if a vendor becomes active in the AS again.

3. Match Vendors by externalId

For every active AS vendor, attempt to find a matching Vendor in Pleo using the externalId field on both ends.

externalId found, Vendor is active in Pleo, details match

The AS vendor is active and the matching Pleo Vendor is also active with the same code, country, defaultCurrency, name, registrationNumber, and taxRegistrationNumber. No action required.

externalId found, Vendor is active in Pleo, details differ

The AS vendor is active and the matching Pleo Vendor is also active, but one or more details differ. Update the Vendor’s code, country, defaultCurrency, name, registrationNumber, and taxRegistrationNumber to match the AS.

externalId found, Vendor is archived in Pleo

The AS vendor is active but the matching Pleo Vendor is archived. Unarchive the Vendor and update its details if they differ from the AS.

externalId not found

The AS vendor is active but no matching Pleo Vendor exists. Create a new Vendor with the vendor’s externalId, code, country, defaultCurrency, name, registrationNumber, and taxRegistrationNumber.
Distinguishing a New Vendor from a Pending Activation
An AS vendor with no matching Pleo Vendor is not always a genuinely new vendor: it can also be an AS record that Vendor Creation already created in Step 1 of its create-and-activate flow, whose Pleo :activate call (Step 2) then failed, timed out, or is still pending, non-concurrently with this Sync run. Before creating, check whether the AS vendor’s identifier is already claimed by an in-flight or retryable Vendor Creation attempt (see Interaction with Vendor Sync on that flow), and skip creation for it if so, leaving it to be picked up by Vendor Creation’s own activation retry instead.
Always Set externalId on Creation
Always set externalId when creating a Vendor from an AS record. Pleo automatically sets a Vendor’s state to ACTIVE when it is created with an externalId. Without one, the Vendor is created in DRAFT state instead, which is the behaviour used by Vendor Creation, not Vendor Sync.
Concurrency with Vendor Creation
Vendor Sync and Vendor Creation’s create-and-activate step must not run concurrently for the same company. If they do, races can occur: Sync may create a duplicate Vendor for an AS record that Vendor Creation already has in flight (still DRAFT in Pleo, and so invisible to Sync’s matching), or Sync may archive a Vendor that Vendor Creation just activated if the AS fetch has not yet caught up. Use the same per-company concurrency lock for both workflows to prevent this.

4. Archive Unmatched Vendors

Pleo Vendors that are active but have no matching active AS vendor must be archived. This covers vendors that were previously present in the AS but have since been deactivated, blocked, or removed. Vendors are never permanently deleted: archiving preserves historical data and allows unarchiving if the vendor becomes active in the AS again.
Skipped Records Are Not Absent Records
“No matching active AS vendor” must be computed only from the AS vendors that passed the skip checks in Invalid or Duplicate externalId above. A Pleo Vendor whose only corresponding AS record was skipped for a data integrity reason is not the same as a Pleo Vendor with no AS record at all, and must not be archived on that basis. Leave it as is, and let it be picked up correctly once the AS-side data integrity issue is fixed and a later sync run resolves it.
Require Two Consecutive Unmatched Runs
A successful fetch is not the same as a complete one: pagination against a live AS can miss a vendor that is concurrently created, updated, or paged past due to replica lag or list-ordering drift, even when every page request itself succeeds (this is distinct from the Partial Fetch Failures rule above, which covers requests that fail outright). Do not archive a Pleo Vendor on its first appearance as unmatched; require it to be unmatched across at least two consecutive successful sync runs before archiving, so a single run’s transient omission cannot cause an incorrect archive. This requires persisting the unmatched-run count or set across separate run invocations, not just within a single run’s memory: otherwise the safeguard is never actually enforced.

Performance and Scalability

Vendor lists can be large. The integration must be able to sync vendor lists at production scale, potentially thousands to tens of thousands of vendors per company (see Pleo API Rate Limit), without delays or degradation, while staying within that rate limit.

What Comes Next?