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

# Detect Draft Vendors

> How to reliably detect new DRAFT vendors created in Pleo, using webhooks or polling, ready to be created in the Accounting System.

export const VendorCreationDetectProcessingOrderDiagram = () => {
  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 linkStyle = isDark ? "" : "linkStyle default stroke:#848989,stroke-width:1px;";
  const diagram = `
%%{init: {"themeVariables": {"fontSize": "12px"}}}%%
flowchart TD
    A[Bookkeeper adds vendor in Pleo] --> B[Vendor created in Pleo, state DRAFT]
    B --> C[v1.vendor.created webhook<br>or 5-min poll]
    C --> D[Integration detects DRAFT vendor]
    D --> E[Begin creation in AS]

   style A white-space:normal,fill:${nodeFill},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 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>;

This page describes how integrations must detect new `DRAFT` vendors created in Pleo, ready to be created in the Accounting System.

This is the **first step** in the Vendor Creation workflow.

## Implementation

See the corresponding how-to article for API usage and step-by-step instructions:

* [How to Detect Draft Vendors](/docs/current/how-tos/accounting-integrations/vendors/how-to-detect-draft-vendors)

## Conceptual Model

Detection identifies `DRAFT` vendors that need to be created in the Accounting System.

It must:

* Detect vendors newly created in Pleo with `state: DRAFT`
* Avoid modifying vendor state in Pleo
* Avoid re-processing a vendor that has already been created in the AS

## Detection Mechanisms

Integrations may use one of the following:

### Webhooks (preferred)

* Subscribe to `v1.vendor.created`
* Trigger creation processing as soon as the event is received
* Pleo triggers this event the moment a bookkeeper adds a vendor with no matching AS record, so this is the fastest path to a usable vendor
* Even when using webhooks as the primary mechanism, pair them with a low-frequency backstop poll (for example, hourly, using the polling mechanism below): webhook delivery is not guaranteed under all failure conditions, and a stranded `DRAFT` vendor with no repair path can otherwise go undetected indefinitely

### Polling (fallback, only if webhooks cannot be supported)

* Periodically call `POST /v1/vendors:search` filtering for vendors in `DRAFT` state
* Use a controlled interval of every 5 minutes

<RememberCallout title="Remember">
  A `DRAFT` vendor only exists once a bookkeeper adds a vendor in Pleo that has no matching record in the Accounting System yet. If every vendor a company uses already exists in the AS, this event may never fire for that company.
</RememberCallout>

## Single-Item Processing

Unlike Export Jobs, there is no batching concept for Vendor Creation. Each `DRAFT` vendor is:

* Detected and processed as its own independent unit of work
* Not blocked by, or blocking, any other `DRAFT` vendor being processed at the same time, with one narrow exception: the per-company concurrency lock shared with Vendor Sync (see [Create and Activate: Failure Handling](/docs/current/integration-design/exports/vendors/integration-design-vendor-creation-create-and-activate#failure-handling)) is scoped to the whole company, so two `DRAFT` vendors for the same company can briefly wait on each other for that lock; vendors in different companies are never affected by each other's locks

## Avoiding Duplicate Processing

Filtering on `state: DRAFT` is not sufficient by itself to prevent the same vendor from being processed twice:

* **Webhook redelivery**: the webhook provider may redeliver the same `v1.vendor.created` event. Persist the event's `eventId` and skip any event already processed.
* **Overlapping polls, or webhook and polling running together**: a poll cycle can re-detect a `DRAFT` vendor that is already being created or activated from a previous poll or from the webhook path, because the vendor genuinely still has `state: DRAFT` until activation completes. Before beginning creation, check whether that vendor id is already marked in-flight (for example, a persisted "processing" record keyed on the Pleo vendor id), and skip it if so.

See [How to Detect Draft Vendors](/docs/current/how-tos/accounting-integrations/vendors/how-to-detect-draft-vendors#handling-edge-cases) for the implementation.

## Key Rules

* Detection must not change a vendor's state in Pleo; only creation and activation do
* Prefer webhooks over polling: they notify the integration immediately, rather than after up to 5 minutes of delay
* If polling, filter strictly on `state: DRAFT` so already-active vendors are not reprocessed
* Treat each detected `DRAFT` vendor as an independent item to create and activate

## Processing Order

<VendorCreationDetectProcessingOrderDiagram />

## Upstream Dependencies

* A bookkeeper adding a new vendor in Pleo's Web App
* Integration authentication configured
* Webhook subscription or scheduled polling implemented

## Downstream Dependencies

* Vendor creation in the Accounting System
* Vendor activation in Pleo

***

## What Comes Next?

* [Create and Activate Vendors](/docs/current/integration-design/exports/vendors/integration-design-vendor-creation-create-and-activate)

***

## Related Reading

* [How to Detect Draft Vendors](/docs/current/how-tos/accounting-integrations/vendors/how-to-detect-draft-vendors)
* [Vendor Creation Workflow Guide](/docs/current/guides/vendor-creation-workflow-guide)
* [Platform Capabilities: Vendor Creation](/docs/current/platform/exports/vendors/vendor-creation-overview)

***
