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

# Vendor Data Linking

> The vendor_data identifier links your system to Didit — binding sessions, transactions, and User/Business entities into one profile. Pay-per-call.

export const AgentPromptAccordion = ({prompt, title = "AI Agent Integration Prompt"}) => {
  const [copied, setCopied] = React.useState(false);
  const handleCopy = e => {
    e.stopPropagation();
    if (!prompt) return;
    navigator.clipboard.writeText(prompt.trim()).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };
  const agents = ["Claude Code", "Codex", "Cursor", "Devin", "Windsurf", "GitHub Copilot"];
  return <div className="didit-agent-card">
      {}
      <div className="didit-agent-titlebar">
        <div className="didit-agent-dots" aria-hidden="true">
          <span className="didit-agent-dot didit-agent-dot-red"></span>
          <span className="didit-agent-dot didit-agent-dot-yellow"></span>
          <span className="didit-agent-dot didit-agent-dot-green"></span>
        </div>
        <span className="didit-agent-filename">{title}</span>
        <button type="button" className={`didit-agent-copy ${copied ? "didit-agent-copy-copied" : ""}`} onClick={handleCopy} title="Copy prompt to clipboard" aria-label={copied ? "Copied!" : "Copy prompt to clipboard"}>
          {copied ? <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              <span>Copied</span>
            </> : <>
              <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
                <rect x="5" y="5" width="9" height="9" rx="1.5" stroke="currentColor" strokeWidth="1.5" />
                <path d="M11 5V3.5A1.5 1.5 0 0 0 9.5 2h-6A1.5 1.5 0 0 0 2 3.5v6A1.5 1.5 0 0 0 3.5 11H5" stroke="currentColor" strokeWidth="1.5" />
              </svg>
              <span>Copy</span>
            </>}
        </button>
      </div>

      {}
      <pre className="didit-agent-body"><code>{prompt.trim()}</code></pre>

      {}
      <div className="didit-agent-footer">
        <span className="didit-agent-footer-label">Paste into</span>
        <div className="didit-agent-chips">
          {agents.map(name => <span key={name} className="didit-agent-chip">{name}</span>)}
        </div>
      </div>
    </div>;
};

<AgentPromptAccordion
  title="Vendor Data Linking Prompt"
  prompt={`# Goal — link every session, transaction, and entity together using \`vendor_data\`

\`vendor_data\` is the string identifier you choose and pass on every API call to bind it to a persistent [User](/entities/users/overview) or [Business](/entities/businesses/overview) entity. Get this right once and you never have to re-key history afterwards.

## Rules

- \`vendor_data\` is **opaque** to Didit. Use your stable internal customer id.
- Choose one canonical id per entity and never change it. Changing it orphans history under a new entity.
- Prefix by entity type when convenient (\`user_...\`, \`biz_...\`) to avoid collisions in your own code.
- Keep it under 128 chars, case-sensitive stable.
- **Never put raw PII in it** — it surfaces in webhooks, logs, and API responses.
- Uniqueness is per application × entity type. User \`user-42\` and Business \`user-42\` are different entities (but don't do this).

## Where it goes

| API | Field |
|---|---|
| \`POST /v3/session/\` | top-level \`vendor_data\` (KYC and KYB) |
| \`POST /v3/transactions/\` | top-level \`vendor_data\` and \`applicant.vendor_data\` / \`counterparty.vendor_data\` |
| \`POST /v3/users/create/\` / \`POST /v3/businesses/create/\` | \`vendor_data\` |
| \`GET /v3/sessions?vendor_data=...\` | query param to retrieve history |
| \`GET /v3/users/{vendor_data}/\` / \`GET /v3/businesses/{vendor_data}/\` | path param |

## Pattern — pre-create the entity, then run a session

\`\`\`bash
# 1) Seed the entity with metadata before any session
curl -X POST https://verification.didit.me/v3/users/create/ \\
-H "x-api-key: $DIDIT_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"vendor_data": "user-42",
"display_name": "Jane Doe",
"metadata": {"tier": "premium", "signup_date": "2026-04-01"}
}'

# 2) Run a KYC session linked to the same entity
curl -X POST https://verification.didit.me/v3/session/ \\
-H "x-api-key: $DIDIT_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"workflow_id": "$WORKFLOW_ID",
"vendor_data": "user-42",
"callback": "https://myapp.com/return"
}'

# 3) Later, retrieve every session for the entity
curl -G https://verification.didit.me/v3/sessions/ \\
-H "x-api-key: $DIDIT_API_KEY" \\
--data-urlencode "vendor_data=user-42"
\`\`\`

## Auto-create semantics

If you create a session with a new \`vendor_data\` and no entity exists, Didit creates the entity automatically with \`status: ACTIVE\` and links the session.

## Failure modes

- Missing \`vendor_data\` on session create → session is orphaned, won't appear in any entity profile, cannot be filtered by \`vendor_data\` later (only by \`session_id\`).
- Different case (\`User-42\` vs \`user-42\`) → two separate entities. Pick a casing convention and stick to it.
- Same \`vendor_data\` across staging and prod apps → no collision; \`vendor_data\` is scoped per application.

## Sources of truth

- /entities/users/operations — full User CRUD
- /entities/businesses/operations — full Business CRUD
- /sessions-api/create-session — session body shape
- /integration/integration-prompt — canonical end-to-end prompt
`}
/>

`vendor_data` is the identifier you supply on every session and transaction to link it to a [User](/entities/users/overview) or [Business](/entities/businesses/overview) entity. It is the single most important field for entity aggregation — get it right and every downstream feature (profile history, transaction monitoring, blocklist enforcement, ongoing AML) works seamlessly.

## What it is

`vendor_data` is a **string** you choose. Didit treats it as an opaque identifier and does not interpret its contents. Typical values:

| Your system            | Good `vendor_data` values                  |
| ---------------------- | ------------------------------------------ |
| Internal user database | `user_1234`, `uuid-v4` of the user         |
| Customer-facing ID     | `CUST-2026-00042`, hashed email            |
| Multi-tenant SaaS      | `tenant_acme:user_1234`                    |
| B2B platform           | `company-hq-global`, `tax-id-US-123456789` |

<Warning>
  Do **not** put PII (emails, phone numbers, raw tax IDs) directly in `vendor_data`. Hash or prefix them. `vendor_data` appears in webhook payloads and is persisted indefinitely while the entity exists.
</Warning>

## How it binds things together

```mermaid theme={null}
flowchart TD
    subgraph YourSystem["Your system"]
      Customer["Customer record: user-42"]
    end
    subgraph Didit["Didit platform"]
      Entity["User entity (vendor_data = user-42)"]
      S1[Session #1]
      S2[Session #2]
      T1[Transaction #1]
      T2[Transaction #2]
      F[Face biometric]
    end
    Customer -.vendor_data.-> Entity
    S1 --> Entity
    S2 --> Entity
    T1 --> Entity
    T2 --> Entity
    F --> Entity
```

When you submit a session or transaction with a `vendor_data` value:

1. Didit looks up the entity in your application with that `vendor_data`.
2. If it exists, the new object is linked to that entity.
3. If it does not exist, Didit creates the entity (with `status: ACTIVE`) and links the new object.

This is true for:

* `POST /v3/session/` — KYC and Business Verification (KYB) sessions
* `POST /v3/transactions/` — transactions (for both applicant and counterparty)
* The `applicant.vendor_data` / `counterparty.vendor_data` fields inside transaction payloads

## Uniqueness and scope

`vendor_data` is **unique per application**, not globally across Didit:

| Scope                                    | Uniqueness guarantee                                                                          |
| ---------------------------------------- | --------------------------------------------------------------------------------------------- |
| Within one application                   | `vendor_data` is unique per entity type (User and Business are separate namespaces)           |
| Across applications in your organization | `vendor_data` is **not** shared — the same value in two apps refers to two different entities |
| Across organizations                     | Not shared — every organization has its own entity tables                                     |

This means you can use the same `vendor_data` in a staging app and a production app without collisions, and you can have a User `user-42` and a Business `user-42` without collision (though this is discouraged for clarity).

## What happens if you omit `vendor_data`

You can create a session without `vendor_data`. In that case:

* No entity is created for the session.
* The session is orphaned — it won't appear in any User or Business profile.
* You cannot later look up the session by `vendor_data` — only by `session_id`.

Use this pattern only for anonymous or one-off verifications where no entity aggregation is needed. For every integration that involves re-verification, transactions, or ongoing monitoring, always provide `vendor_data`.

## Example: pre-create an entity, then run sessions

```bash theme={null}
# 1. Pre-create the User with initial metadata
curl -X POST https://verification.didit.me/v3/users/create/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "vendor_data": "user-42",
    "display_name": "Jane Doe",
    "metadata": { "tier": "premium", "signup_date": "2026-04-01" }
  }'

# 2. Create a User Verification (KYC) session for the same user
curl -X POST https://verification.didit.me/v3/session/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wf_kyc_standard",
    "vendor_data": "user-42"
  }'

# 3. Later, submit a transaction tied to the same user
curl -X POST https://verification.didit.me/v3/transactions/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "txn_id": "tx-0001",
    "direction": "OUTBOUND",
    "amount": "500.00",
    "currency": "EUR",
    "applicant": { "vendor_data": "user-42" },
    "counterparty": { "name": "Acme Corp" }
  }'
```

All three calls are linked to the same User entity. When you later `GET /v3/users/user-42/`, you'll see the session count, approved/declined counters, linked transactions, and latest profile data.

## Migrating external IDs

If you're adopting Didit after an existing KYC vendor, pass your existing stable user IDs as `vendor_data` from day one. This makes it easy to:

* Reconcile Didit data with your internal database.
* Bulk-load historical users via console CSV import before running any sessions.
* Preserve relationships when you later migrate to Didit for transaction monitoring.

## Rules, conventions, and best practices

| Rule                                                               | Why                                                                |
| ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| Choose one canonical identifier per entity and never change it     | Changes create a new entity and orphan history                     |
| Prefix `vendor_data` values by entity type (`user_...`, `biz_...`) | Prevents accidental collisions between namespaces in your own code |
| Keep `vendor_data` case-sensitive stable                           | Didit does not normalize case                                      |
| Keep `vendor_data` length under 128 chars                          | Fits comfortably in database indexes                               |
| Never expose raw PII                                               | `vendor_data` appears in webhooks, audit logs, and API responses   |

## Next steps

<CardGroup cols={3}>
  <Card title="Users overview" icon="user" href="/entities/users/overview">
    Deep dive on User entities and operations.
  </Card>

  <Card title="Businesses overview" icon="building" href="/entities/businesses/overview">
    Deep dive on Business entities and operations.
  </Card>

  <Card title="Create session" icon="play" href="/sessions-api/create-session">
    Start a verification for a vendor\_data.
  </Card>

  <Card title="Create transaction" icon="arrow-right-to-bracket" href="/management-api/transactions/create">
    Submit a transaction linked to an entity.
  </Card>
</CardGroup>
