> ## Documentation Index
> Fetch the complete documentation index at: https://developers.pleo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Vendor Sync Overview

> Learn how Vendor Sync keeps Vendors in Pleo aligned with the active vendors in your Accounting System, and what the integrator is responsible for.

export const VendorSyncHighLevelProcessDiagram = () => {
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const check = () => setIsDark(document.documentElement.classList.contains("dark"));
    check();
    const observer = new MutationObserver(check);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, []);
  const nodeFill = isDark ? "#212222" : "#EEF4F4";
  const nodeStroke = isDark ? "#848989" : "#E1E6E6";
  const nodeTextStyle = isDark ? ",color:#EEF4F4" : ",color:#131414";
  const outerFill = "transparent";
  const linkStyle = isDark ? "" : "linkStyle default stroke:#848989,stroke-width:1px;";
  const themeVariables = {
    fontSize: "12px",
    ...isDark ? {} : {
      edgeLabelBackground: "#FAFCFC"
    }
  };
  const diagram = `
%%{init: {"themeVariables": ${JSON.stringify(themeVariables)}}}%%
flowchart TD
    A[Accounting System<br>Vendors]
    B[Step 1:<br>Fetch Active Vendors from AS]
    C[Step 2:<br>Fetch Vendors from Pleo]
    D[Step 3:<br>Reconcile by externalId]
    E[Pleo<br>Vendors]

    A --> B --> C --> D --> E

    style A white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style B white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style C white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style D white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style E white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
${linkStyle}
`;
  return <Mermaid chart={diagram} />;
};

export const VendorSyncRelationshipDiagram = () => {
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const check = () => setIsDark(document.documentElement.classList.contains("dark"));
    check();
    const observer = new MutationObserver(check);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, []);
  const nodeFill = isDark ? "#212222" : "#EEF4F4";
  const nodeStroke = isDark ? "#848989" : "#E1E6E6";
  const nodeTextStyle = isDark ? ",color:#EEF4F4" : ",color:#131414";
  const outerFill = "transparent";
  const subgraphFill = isDark ? "#131414" : "#ffffff";
  const subgraphStroke = isDark ? "#848989" : "#6B7070";
  const subgraphTextStyle = isDark ? ",color:#EEF4F4" : ",color:#131414";
  const pleoSubgraphTextStyle = ",color:#FEB6FE";
  const linkStyle = isDark ? "" : "linkStyle default stroke:#848989,stroke-width:1px;";
  const themeVariables = {
    fontSize: "12px",
    ...isDark ? {} : {
      edgeLabelBackground: "#FAFCFC"
    }
  };
  const diagram = `
%%{init: {"themeVariables": ${JSON.stringify(themeVariables)}}}%%
flowchart TD

    AS_vendors["Accounting System<br>Vendors"]
    Bookkeeper["Bookkeeper"]

    subgraph integration["Integration"]
        vendor_sync["Vendor Sync"]
        export["Export API"]
    end

    subgraph pleo["Pleo"]
        vendors["Vendors"]
        expense["Expense / Invoice"]
        expense_export["Expense Export"]
    end

    AS_out["Accounting System"]

    AS_vendors --> vendor_sync
    vendor_sync -->|"vendors synced in"| vendors
    Bookkeeper -->|"tags expense<br>with a vendor"| expense
    vendors -->|"available to tag"| expense
    expense -->|"bookkeeper confirms<br>before export"| expense_export
    expense_export --> export
    export -->|"exported against<br>the correct vendor"| AS_out

    style AS_vendors white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style AS_out white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style Bookkeeper white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style vendor_sync white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style export white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style vendors white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style expense white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style expense_export white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style integration fill:${subgraphFill},stroke:${subgraphStroke}${subgraphTextStyle}
    style pleo fill:${subgraphFill},stroke:${subgraphStroke}${pleoSubgraphTextStyle}
${linkStyle}
`;
  return <Mermaid chart={diagram} />;
};

export const VendorSyncDirectionDiagram = () => {
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const check = () => setIsDark(document.documentElement.classList.contains("dark"));
    check();
    const observer = new MutationObserver(check);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, []);
  const nodeFill = isDark ? "#212222" : "#EEF4F4";
  const nodeStroke = isDark ? "#848989" : "#E1E6E6";
  const nodeTextStyle = isDark ? ",color:#EEF4F4" : ",color:#131414";
  const outerFill = "transparent";
  const subgraphFill = isDark ? "#131414" : "#ffffff";
  const subgraphStroke = isDark ? "#848989" : "#6B7070";
  const subgraphTextStyle = isDark ? ",color:#EEF4F4" : ",color:#131414";
  const pleoSubgraphTextStyle = ",color:#FEB6FE";
  const linkStyle = isDark ? "" : "linkStyle default stroke:#848989,stroke-width:1px;";
  const themeVariables = {
    fontSize: "18px",
    ...isDark ? {} : {
      edgeLabelBackground: "#FAFCFC"
    }
  };
  const diagram = `
%%{init: {"themeVariables": ${JSON.stringify(themeVariables)}}}%%
flowchart RL

subgraph AS["Accounting System / ERP"]
    source["Vendors"]
end

subgraph Integration["Vendor Sync Integration"]
    sync["Sync Logic + Reconciliation Engine"]
end

subgraph Pleo["Pleo"]
    target["Vendors"]
end

AS -.-> Integration
Integration -->|"Pleo Vendors API"| Pleo

style source white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
style sync white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
style target white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
style AS fill:${subgraphFill},stroke:${subgraphStroke}${subgraphTextStyle}
style Integration fill:${subgraphFill},stroke:${subgraphStroke}${subgraphTextStyle}
style Pleo fill:${subgraphFill},stroke:${subgraphStroke}${pleoSubgraphTextStyle}
${linkStyle}
`;
  return <Mermaid chart={diagram} />;
};

export const NoteCallout = ({title, children}) => <div className="callout-box callout-note">
    <div className="callout-row">
      <span className="callout-icon">
        <svg width="22" height="22" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M208,104a79.86,79.86,0,0,1-30.59,62.92A24.29,24.29,0,0,0,168,186v6a8,8,0,0,1-8,8H96a8,8,0,0,1-8-8v-6a24.11,24.11,0,0,0-9.3-19A79.87,79.87,0,0,1,48,104.45C47.76,61.09,82.72,25,126.07,24A80,80,0,0,1,208,104Z" opacity="0.2" /><path d="M176,232a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h80A8,8,0,0,1,176,232Zm40-128a87.55,87.55,0,0,1-33.64,69.21A16.24,16.24,0,0,0,176,186v6a16,16,0,0,1-16,16H96a16,16,0,0,1-16-16v-6a16,16,0,0,0-6.23-12.66A87.59,87.59,0,0,1,40,104.49C39.74,56.83,78.26,17.14,125.88,16A88,88,0,0,1,216,104Zm-16,0a72,72,0,0,0-73.74-72c-39,.92-70.47,33.39-70.26,72.39a71.65,71.65,0,0,0,27.64,56.3A32,32,0,0,1,96,186v6h64v-6a32.15,32.15,0,0,1,12.47-25.35A71.65,71.65,0,0,0,200,104Zm-16.11-9.34a57.6,57.6,0,0,0-46.56-46.55,8,8,0,0,0-2.66,15.78c16.57,2.79,30.63,16.85,33.44,33.45A8,8,0,0,0,176,104a9,9,0,0,0,1.35-.11A8,8,0,0,0,183.89,94.66Z" /></svg>
      </span>
      <div>
        {title && <div className="callout-title">
            {title}
          </div>}
        <div className="callout-body">
          {children}
        </div>
      </div>
    </div>
  </div>;

export const RememberCallout = ({title, children}) => <div className="callout-box callout-remember">
    <div className="callout-row">
      <span className="callout-icon">
        <svg width="22" height="22" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M229.66,98.34,172.39,155.8c11.46,22.93-1.72,45.86-10.11,57a8,8,0,0,1-12,.83L42.34,105.76A8,8,0,0,1,43,93.85c29.65-23.92,57.4-10,57.4-10l57.27-57.46a8,8,0,0,1,11.31,0L229.66,87A8,8,0,0,1,229.66,98.34Z" opacity="0.2" /><path d="M235.32,81.37,174.63,20.69a16,16,0,0,0-22.63,0L98.37,74.49c-10.66-3.34-35-7.37-60.4,13.14a16,16,0,0,0-1.29,23.78L85,159.71,42.34,202.34a8,8,0,0,0,11.32,11.32L96.29,171l48.29,48.29A16,16,0,0,0,155.9,224c.38,0,.75,0,1.13,0a15.93,15.93,0,0,0,11.64-6.33c19.64-26.1,17.75-47.32,13.19-60L235.33,104A16,16,0,0,0,235.32,81.37ZM224,92.69h0l-57.27,57.46a8,8,0,0,0-1.49,9.22c9.46,18.93-1.8,38.59-9.34,48.62L48,100.08c12.08-9.74,23.64-12.31,32.48-12.31A40.13,40.13,0,0,1,96.81,91a8,8,0,0,0,9.25-1.51L163.32,32,224,92.68Z" /></svg>
      </span>
      <div>
        {title && <div className="callout-title">
            {title}
          </div>}
        <div className="callout-body">
          {children}
        </div>
      </div>
    </div>
  </div>;

<NoteCallout title="New to Pleo Vendors?">
  This page assumes you already know what a Vendor is, and that Vendor Sync is the flow you need. If you're not sure, start with [Supplier vs Vendor](/docs/current/platform/exports/vendors/supplier-vs-vendor-overview) for the underlying concept, then [Vendor Creation vs Vendor Sync](/docs/current/platform/exports/vendors/vendor-creation-vs-vendor-sync-overview) to confirm which of the two flows applies to your scenario.
</NoteCallout>

**Vendor Sync** is how Pleo keeps its Vendor records up to date by synchronising vendor data from an external Accounting System into Pleo.

It ensures bookkeepers always have an accurate, current list of vendors available to tag on expenses (once Vendor Tagging is enabled), so that spend can be tracked and bookkept against the correct vendor in the Accounting System.

This is the reverse of [Vendor Creation](/docs/current/platform/exports/vendors/vendor-creation-overview), which lets a bookkeeper add a new vendor directly in Pleo, even if it doesn't exist in the Accounting System yet.

## Purpose of Vendor Sync

Vendor Sync exists to:

* Remove the need to manually create or maintain Vendor records in Pleo
* Reflect the current state of active vendors from the Accounting System
* Enable accurate, auditable bookkeeping by ensuring expenses and invoices carry the correct vendor before export
* Keep vendor data synchronised between systems

## Core Concept

Vendor Sync is based on a direct mapping between systems:

| Accounting System              | Pleo                           |
| ------------------------------ | ------------------------------ |
| Vendor record                  | Vendor                         |
| Vendor identifier              | Vendor `externalId`            |
| Vendor code                    | Vendor `code`                  |
| Vendor name                    | Vendor `name`                  |
| Vendor country                 | Vendor `country`               |
| Vendor default currency        | Vendor `defaultCurrency`       |
| Vendor registration number     | Vendor `registrationNumber`    |
| Vendor tax registration number | Vendor `taxRegistrationNumber` |

For detailed field-level mapping, see [Vendor Sync Data Mapping](/docs/current/integration-design/accounting-integrations/imports/vendors/integration-design-vendor-sync-data-mapping).

### How Vendors Are Used in Pleo

Vendor Sync works alongside the Export API to enable **vendor-based bookkeeping**. Once vendors are synced and Vendor Tagging is activated, spenders and bookkeepers can tag an expense or invoice with a vendor before it is exported, and the integration bookkeeps the entry against that vendor in the Accounting System, typically using the Accounts Payable bookkeeping method.

<VendorSyncRelationshipDiagram />

The full chain is:

1. **Accounting System Vendors:** the source of vendor data, synced into Pleo via Vendor Sync
2. **Pleo Vendors:** bookkeepers activate Vendor Tagging and select which vendor to use per expense or invoice
3. **Expenses and Invoices:** a spender or bookkeeper tags the entry with a vendor before export
4. **Export:** the entry is exported to the Accounting System against the correct vendor, typically using the Accounts Payable bookkeeping method

<RememberCallout title="Remember">
  Activating Vendor Tagging and assigning a vendor to an expense are actions taken explicitly in the Pleo Web App. They are not performed automatically by Vendor Sync. See [How to Enable Vendor-Based Bookkeeping](/docs/current/how-tos/accounting-integrations/how-to-enable-vendor-based-bookkeeping).
</RememberCallout>

This is why keeping Pleo's Vendors accurate matters: if vendor data is stale or missing, bookkeepers cannot tag expenses to the correct vendor, and Accounts Payable bookkeeping cannot correctly resolve a vendor liability.

### What Happens in Pleo Once Synchronised

* Each active vendor from the Accounting System is reflected as a Vendor in Pleo, in `ACTIVE` state
* Vendors are available for bookkeepers to tag on expenses and invoices, provided Vendor Tagging is enabled for the company (see the Remember note above)
* If a vendor's details change in the Accounting System, they are updated in Pleo on the next sync
* Vendors no longer active in the Accounting System are archived in Pleo

This ensures expenses and invoices always reference a current, valid vendor without requiring manual input.

## System Guarantees

These are invariant rules that always hold true regardless of implementation or sync frequency.

| Guarantee                 | Description                                                                                      |
| ------------------------- | ------------------------------------------------------------------------------------------------ |
| Source of Truth           | The Accounting System is the authoritative source of vendor data for this sync direction         |
| Structural Mapping        | Vendors map directly from the Accounting System into Pleo                                        |
| Identity Model            | Matching is performed using `externalId`, not vendor name                                        |
| Non-Destructive Behaviour | Vendors are never deleted; they are only archived when no longer active in the Accounting System |
| Idempotency               | Re-running a sync produces the same final state without duplication                              |

## Responsibility Model

### Integrator Responsibilities

The integration is responsible for all synchronisation logic and API interaction.

| Area           | Responsibility                                                        |
| -------------- | --------------------------------------------------------------------- |
| Connection     | Connect to the Accounting System                                      |
| Data Retrieval | Retrieve active vendors from the Accounting System                    |
| Sync Execution | Execute reconciliation operations in Pleo via the Vendors API         |
| Scheduling     | Define and execute sync schedule (including optional manual triggers) |

### Pleo Responsibilities

Pleo provides storage, user experience, and downstream usage of vendors.

| Area           | Responsibility                                       |
| -------------- | ---------------------------------------------------- |
| Data Storage   | Store Vendors                                        |
| User Interface | Display Vendors for tagging on expenses and invoices |
| Data Retention | Retain archived Vendors for historical consistency   |

## High-Level Process

<VendorSyncHighLevelProcessDiagram />

Vendor Sync runs as a single reconciliation process:

1. **Fetch active vendors** from the Accounting System
2. **Fetch Vendors from Pleo** (active and archived)
3. **Reconcile:** match by `externalId` and apply create, update, unarchive, or archive operations

Each sync run reconciles Pleo against the current state of the Accounting System.

## Operational Model

### Sync Direction

Vendor Sync is one-way for this flow:

<VendorSyncDirectionDiagram />

* The **Accounting System** is the **source of truth** for existing vendors
* The integration synchronises data from the Accounting System into Pleo
* Pleo does not modify Accounting System data as part of this sync

<RememberCallout title="Remember">
  A bookkeeper can also create a brand-new vendor directly in Pleo when no corresponding record exists yet in the Accounting System. That flow moves in the opposite direction, Pleo → Accounting System, and is covered separately in [Vendor Creation Overview](/docs/current/platform/exports/vendors/vendor-creation-overview).
</RememberCallout>

### Operational Constraints

| Constraint            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Scheduling Ownership  | The integration is responsible for defining when sync runs occur, including optional manual triggers                                                                                                                                                                                                                                                                                                                                                                                     |
| Sync Execution        | The integration is responsible for executing sync runs and applying all changes to Pleo via the API                                                                                                                                                                                                                                                                                                                                                                                      |
| Execution Model       | Each sync run performs full reconciliation of Pleo against the Accounting System                                                                                                                                                                                                                                                                                                                                                                                                         |
| Rate Limits           | The integration must respect two separate rate limits: the target Accounting System's own API rate limit (varies by AS, the integration's own responsibility to determine), and [Pleo's Vendors API rate limit](/docs/current/authentication/api-base-urls#rate-limits) when calling Pleo.                                                                                                                                                                                               |
| Required Scopes       | The integration's credential must include the Vendors API scopes needed to read and write vendor data (see [Vendors API Scopes](/reference/vendor/vendor-api-scopes)). A missing scope causes the specific request to fail with `403`, not `401`, distinct from the expired/revoked-credential case below. Request the required scope during [OAuth client registration](/docs/current/how-tos/oauth/how-to-register-an-oauth-client#technical-information) or when creating an API Key. |
| Credential Failures   | If a sync run hits a `401`/`403` due to an expired, revoked, or rotated credential, abort the run rather than reconciling with partial results, then resume on the next cycle once credentials are restored. See [How to Handle Token Expiry or Revocation](/docs/current/how-tos/oauth/how-to-handle-token-expiry-or-revocation).                                                                                                                                                       |
| Concurrency           | Sync runs must not overlap; only one execution may run at a time. See [collision handling](/docs/current/integration-design/accounting-integrations/imports/vendors/integration-design-vendor-sync-periodicity#ad-hoc-vendor-sync) for what to do if a trigger arrives while a run is already in progress.                                                                                                                                                                               |
| Forward Compatibility | New vendor fields, new `state` values, and additional pagination metadata may be added to Vendors API responses over time. Build the integration to ignore unrecognised fields and values rather than failing on them, and treat this suite's documented field list and `state` values (`DRAFT`, `ACTIVE`, `ARCHIVED`) as the current, not exhaustive-forever, set.                                                                                                                      |

### Sync Lifecycle and Frequency

The integration is responsible for triggering all sync runs. For schedule, frequency, and rate limit details, see [Vendor Sync Periodicity and Scheduling](/docs/current/integration-design/accounting-integrations/imports/vendors/integration-design-vendor-sync-periodicity).

***

## Related Reading

* [Supplier vs Vendor](/docs/current/platform/exports/vendors/supplier-vs-vendor-overview)
* [Integration Design: Vendor Sync Implementation Overview](/docs/current/integration-design/accounting-integrations/imports/vendors/integration-design-vendor-sync-overview)
* [Vendor Sync Workflow Guide](/docs/current/guides/accounting-integrations/imports/vendor-sync-workflow-guide)
* [Platform Capabilities: Vendor Creation Overview](/docs/current/platform/exports/vendors/vendor-creation-overview)
* [How to Activate Vendor Tagging](/docs/current/how-tos/accounting-integrations/how-to-enable-vendor-based-bookkeeping#1-activate-vendor-tagging) (or [chat with support](https://help.pleo.io/en/support/solutions/articles/103000360463-how-to-activate-vendor-tagging-in-pleo) <Icon icon="arrow-up-right-from-square" size={14} />)
* [Connection and Authorisation Overview](/docs/current/integration-design/auth/integration-design-auth-overview)

***
