> ## 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.

# Tags Sync Overview

export const TagsSyncHighLevelProcessDiagram = () => {
  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: "10px",
    ...isDark ? {} : {
      edgeLabelBackground: "#FAFCFC"
    }
  };
  const diagram = `
%%{init: {"themeVariables": ${JSON.stringify(themeVariables)}}}%%
flowchart TD
    A[Accounting System<br>Dimensions & Values]
    B[Step 1:<br>Select Dimensions]
    C[Step 2:<br>Sync Tag Groups with Dimensions]
    D[Step 3:<br>Sync Tags with Dimension Values]
    E[Pleo<br>Tag Groups & Tags]
    F[Expense Tagging]

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

    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}
    style F white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
${linkStyle}
`;
  return <Mermaid chart={diagram} />;
};

export const TagsSyncRelationshipDiagram = () => {
  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_dims["Accounting System<br>Dimensions & Values"]
    Spender["Spender"]

    subgraph integration["Integration"]
        tags_sync["Tags Sync"]
        export_api["Export API"]
    end

    subgraph pleo["Pleo"]
        tag_groups["Tag Groups & Tags"]
        expense["Expense"]
        expense_export["Expense Export"]
    end

    AS_out["Accounting System"]

    AS_dims --> tags_sync
    tags_sync -->|"Tag Groups & Tags synced in"| tag_groups
    Spender -->|"submits expense,<br>assigns Tags"| expense
    tag_groups -->|"Tags available<br>for selection"| expense
    expense -->|"bookkeeper confirms"| expense_export
    expense_export --> export_api
    export_api -->|"exported with Tags"| AS_out

    style AS_dims white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style AS_out white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style Spender white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
    style tags_sync white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style export_api white-space:normal,fill:${nodeFill},stroke:${nodeStroke}${nodeTextStyle}
    style tag_groups 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 TagsSyncDirectionDiagram = () => {
  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["Dimensions & Dimension Values"]
end

subgraph Config["Dimension Selection"]
    selection["Selected Dimensions (max 5)"]
end

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

subgraph Pleo["Pleo"]
    target["Tag Groups & Tags"]
end

AS -.-> Config
Config -.-> Integration
Integration -->|"Pleo Tags API"| Pleo

selection -. controls .-> sync

style source white-space:normal,fill:${outerFill},stroke:${nodeStroke}${nodeTextStyle}
style selection white-space:normal,fill:${nodeFill},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 Config fill:${subgraphFill},stroke:${subgraphStroke}${subgraphTextStyle}
style Integration fill:${subgraphFill},stroke:${subgraphStroke}${subgraphTextStyle}
style Pleo fill:${subgraphFill},stroke:${subgraphStroke}${pleoSubgraphTextStyle}
${linkStyle}
`;
  return <Mermaid chart={diagram} />;
};

**Tags Sync** is how Pleo keeps its Tags up to date by synchronising Accounting Dimensions from an external Accounting System into Pleo.

It ensures that bookkeepers always work with an accurate and current representation of Accounting Dimensions when categorising expenses in Pleo.

## Purpose of Tags Sync

Tags Sync exists to:

* Remove the need to manually create or maintain Tags in Pleo
* Reflect the current structure of Accounting Dimensions in Pleo
* Enable consistent expense categorisation aligned with the Accounting System
* Keep accounting metadata synchronised between systems

## Core Concept

Tags Sync is based on a direct mapping between systems:

| Accounting System    | Pleo      |
| -------------------- | --------- |
| Accounting Dimension | Tag Group |
| Dimension Value      | Tag       |

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

### How Tags Are Used in Pleo

Once synced, Tags are available for spenders to assign to expenses. When an expense is exported, the assigned Tags are included, allowing the Accounting System to categorise and report on expenses using its own Dimension structure.

<TagsSyncRelationshipDiagram />

The full chain is:

1. **Accounting System Dimensions and Values:** the source of tag structure, synced into Pleo via Tags Sync
2. **Expenses:** when a spender submits an expense, they can apply Tags to it
3. **Export:** the expense is exported to the Accounting System with the assigned Tags attached

### What Happens in Pleo Once Synchronised

* Each Accounting Dimension becomes a Tag Group in Pleo
* Each Dimension Value becomes a Tag
* Each Tag belongs to exactly one Tag Group
* Bookkeepers use Tags to categorise expenses
* Tags are used in downstream export processes (outside of Tags Sync)

This ensures expenses reflect the Accounting System structure without manual setup in Pleo.

## 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 all Dimensions and Dimension Values                      |
| Structural Mapping        | Dimensions map to Tag Groups, and Dimension Values map to Tags                                                |
| Identity Model            | Matching is performed using codes, not names                                                                  |
| Case-Insensitive Matching | Code matching ignores case differences                                                                        |
| Non-Destructive Behaviour | Tags and Tag Groups are never deleted; they are only archived when no longer present 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 Dimensions and Dimension Values                              |
| Configuration  | Manage which Dimensions are selected for synchronisation              |
| Sync Execution | Execute reconciliation operations in Pleo via the Tags API            |
| Scheduling     | Define and execute sync schedule (including optional manual triggers) |

### Pleo Responsibilities

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

| Area               | Responsibility                                                 |
| ------------------ | -------------------------------------------------------------- |
| Data Storage       | Store Tag Groups and Tags                                      |
| User Interface     | Display Tags for expense categorisation                        |
| Expense Assignment | Allow users to assign Tags to expenses                         |
| Data Retention     | Retain archived Tags and Tag Groups for historical consistency |

## High-Level Process

<TagsSyncHighLevelProcessDiagram />

Tags Sync runs in three steps:

1. **Select Dimensions**: configure which Accounting Dimensions to synchronise (first connection only)
2. **Sync Tag Groups with Dimensions**: reconcile Tag Groups in Pleo with the selected Dimensions
3. **Sync Tags with Dimension Values**: reconcile Tags within each Tag Group with the corresponding Dimension Values

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

## Operational Model

### Sync Direction

Tags Sync is one-way only:

<TagsSyncDirectionDiagram />

* The **Accounting System** is the **source of truth**
* The integration synchronises data from the Accounting System into Pleo
* Pleo does not modify Accounting System data
* Pleo data is only used for identity matching and reconciliation of existing entities, never as a source of truth for Dimensions or Dimension Values

### Operational Constraints

These define how the integration must execute Tags Sync.

| 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 Accounting System API rate limits and adjust scheduling accordingly. See [Pleo API rate limits](/docs/current/authentication/api-base-urls#rate-limits). |
| Concurrency          | Sync runs must not overlap; only one execution may run at a time                                                                                                                      |

### Sync Lifecycle and Frequency

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

## Dimension Selection

The integration controls which Accounting Dimensions participate in Tags Sync. Only selected Dimensions are synchronised into Pleo.

Dimension selection determines:

* which Dimensions are included in reconciliation
* which Tag Groups and Tags are maintained in Pleo
* which accounting structures become available for expense categorisation

Detailed selection behaviour and implementation guidance are covered in [Integration Design](/docs/current/integration-design/accounting-integrations/imports/tags/integration-design-tags-dimension-selection).

***

## Related Reading

* [Integration Design: Tags Sync Overview](/docs/current/integration-design/accounting-integrations/imports/tags/integration-design-tags-overview)
* [Tags Sync Workflow Guide](/docs/current/guides/accounting-integrations/imports/tags-sync-workflow-guide)
* [Connection and Authorisation Overview](/docs/current/integration-design/auth/integration-design-auth-overview)

***
