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

# Onboarding

> Offsite onboarding timeline, account architecture, and set up steps.

export const OffsiteVendorAccountArchitectureDiagram = () => <div className="offsite-vendor-account-architecture not-prose" style={{
  margin: "1.5rem 0",
  overflowX: "auto"
}}>
    <style>{`
      .offsite-vendor-account-architecture svg {
        display: block;
        width: 100%;
        max-width: 882px;
        height: auto;
      }

      .offsite-vendor-account-architecture .marketplace-box {
        fill: #dcfce7;
        stroke: #16a34a;
      }

      .offsite-vendor-account-architecture .topsort-box {
        fill: #dbeafe;
        stroke: #2563eb;
      }

      .offsite-vendor-account-architecture .section-title,
      .offsite-vendor-account-architecture .box-label,
      .offsite-vendor-account-architecture .legend-label,
      .offsite-vendor-account-architecture .column-label {
        fill: #111827;
        font-family: Inter, system-ui, -apple-system, sans-serif;
      }

      .offsite-vendor-account-architecture .section-title {
        font-size: 15px;
        font-weight: 700;
      }

      .offsite-vendor-account-architecture .box-label {
        font-size: 12px;
        font-weight: 600;
      }

      .offsite-vendor-account-architecture .column-label,
      .offsite-vendor-account-architecture .legend-label {
        font-size: 11px;
        font-weight: 500;
      }

      .offsite-vendor-account-architecture .connector {
        stroke: #6b7280;
        stroke-width: 1.5;
        fill: none;
      }

      .dark .offsite-vendor-account-architecture .marketplace-box {
        fill: #14532d;
        stroke: #4ade80;
      }

      .dark .offsite-vendor-account-architecture .topsort-box {
        fill: #1e3a8a;
        stroke: #60a5fa;
      }

      .dark .offsite-vendor-account-architecture .section-title,
      .dark .offsite-vendor-account-architecture .box-label,
      .dark .offsite-vendor-account-architecture .legend-label,
      .dark .offsite-vendor-account-architecture .column-label {
        fill: #f3f4f6;
      }

      .dark .offsite-vendor-account-architecture .connector {
        stroke: #9ca3af;
      }
    `}</style>

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 882 540" role="img" aria-label="Diagram of Google and Meta offsite account architecture showing retailer and Topsort-managed brand accounts">
      <text className="section-title" x="221" y="28" textAnchor="middle">
        Google Offsite Accounts
      </text>
      <text className="section-title" x="662" y="28" textAnchor="middle">
        Meta Offsite Accounts
      </text>

      <line className="connector" x1="477" y1="40" x2="477" y2="470" strokeDasharray="4 4" />

      <text className="column-label" x="144" y="58" textAnchor="middle">
        Merchant Center
      </text>
      <text className="column-label" x="360" y="58" textAnchor="middle">
        Ad Accounts
      </text>

      <rect className="marketplace-box" x="63" y="72" width="162" height="44" rx="8" strokeWidth="2" />
      <text className="box-label" x="144" y="99" textAnchor="middle">
        Retailer MCA
      </text>

      <line className="connector" x1="144" y1="116" x2="144" y2="132" />

      <rect className="topsort-box" x="86" y="132" width="117" height="32" rx="6" strokeWidth="2" />
      <text className="box-label" x="144" y="153" textAnchor="middle">
        Brand MC Acct 1
      </text>

      <line className="connector" x1="144" y1="164" x2="144" y2="176" />

      <rect className="topsort-box" x="86" y="176" width="117" height="32" rx="6" strokeWidth="2" />
      <text className="box-label" x="144" y="197" textAnchor="middle">
        Brand MC Acct 2
      </text>

      <text className="column-label" x="144" y="224" textAnchor="middle">
        ...
      </text>

      <line className="connector" x1="144" y1="232" x2="144" y2="244" />

      <rect className="topsort-box" x="86" y="244" width="117" height="32" rx="6" strokeWidth="2" />
      <text className="box-label" x="144" y="265" textAnchor="middle">
        Brand MC Acct N
      </text>

      <rect className="marketplace-box" x="279" y="72" width="162" height="44" rx="8" strokeWidth="2" />
      <text className="box-label" x="360" y="99" textAnchor="middle">
        Retailer MCC
      </text>

      <line className="connector" x1="360" y1="116" x2="360" y2="132" />

      <rect className="topsort-box" x="279" y="132" width="162" height="44" rx="8" strokeWidth="2" />
      <text className="box-label" x="360" y="159" textAnchor="middle">
        Topsort MCC
      </text>

      <line className="connector" x1="360" y1="176" x2="360" y2="192" />

      <rect className="topsort-box" x="302" y="192" width="117" height="32" rx="6" strokeWidth="2" />
      <text className="box-label" x="360" y="213" textAnchor="middle">
        Brand Ad Acct 1
      </text>

      <line className="connector" x1="360" y1="224" x2="360" y2="236" />

      <rect className="topsort-box" x="302" y="236" width="117" height="32" rx="6" strokeWidth="2" />
      <text className="box-label" x="360" y="257" textAnchor="middle">
        Brand Ad Acct 2
      </text>

      <text className="column-label" x="360" y="284" textAnchor="middle">
        ...
      </text>

      <line className="connector" x1="360" y1="292" x2="360" y2="304" />

      <rect className="topsort-box" x="302" y="304" width="117" height="32" rx="6" strokeWidth="2" />
      <text className="box-label" x="360" y="325" textAnchor="middle">
        Brand Ad Acct N
      </text>

      <rect className="marketplace-box" x="572" y="72" width="180" height="44" rx="8" strokeWidth="2" />
      <text className="box-label" x="662" y="99" textAnchor="middle">
        Retailer Business Manager
      </text>

      <line className="connector" x1="662" y1="116" x2="662" y2="145" />
      <line className="connector" x1="590" y1="145" x2="734" y2="145" />
      <line className="connector" x1="590" y1="145" x2="590" y2="165" />
      <line className="connector" x1="734" y1="145" x2="734" y2="165" />

      <rect className="topsort-box" x="536" y="165" width="108" height="36" rx="6" strokeWidth="2" />
      <text className="box-label" x="590" y="188" textAnchor="middle">
        Brand Ad Acct 1
      </text>

      <rect className="topsort-box" x="536" y="215" width="108" height="36" rx="6" strokeWidth="2" />
      <text className="box-label" x="590" y="238" textAnchor="middle">
        Brand Ad Acct 2
      </text>

      <text className="column-label" x="590" y="272" textAnchor="middle">
        ...
      </text>

      <rect className="topsort-box" x="536" y="285" width="108" height="36" rx="6" strokeWidth="2" />
      <text className="box-label" x="590" y="308" textAnchor="middle">
        Brand Ad Acct N
      </text>

      <rect className="topsort-box" x="680" y="165" width="108" height="36" rx="6" strokeWidth="2" />
      <text className="box-label" x="734" y="188" textAnchor="middle">
        Brand Child BM 1
      </text>

      <rect className="topsort-box" x="680" y="215" width="108" height="36" rx="6" strokeWidth="2" />
      <text className="box-label" x="734" y="238" textAnchor="middle">
        Brand Child BM 2
      </text>

      <text className="column-label" x="734" y="272" textAnchor="middle">
        ...
      </text>

      <rect className="topsort-box" x="680" y="285" width="108" height="36" rx="6" strokeWidth="2" />
      <text className="box-label" x="734" y="308" textAnchor="middle">
        Brand Child BM N
      </text>

      <rect className="marketplace-box" x="36" y="470" width="18" height="18" rx="3" strokeWidth="2" />
      <text className="legend-label" x="61" y="484">
        Marketplace provides and manages
      </text>

      <rect className="topsort-box" x="320" y="470" width="18" height="18" rx="3" strokeWidth="2" />
      <text className="legend-label" x="345" y="484">
        Topsort creates and manages
      </text>
    </svg>
  </div>;

export const LastUpdated = ({date, lang = "en"}) => {
  const translations = {
    en: "Last updated:",
    es: "Última actualización:",
    pt: "Última atualização:",
    fr: "Dernière mise à jour:",
    de: "Zuletzt aktualisiert:"
  };
  const label = translations[lang] || translations.en;
  return <>
<style>{`
.last-updated-component {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
border-radius: 8px;
margin-top: 12px;
margin-bottom: 16px;
font-size: 14px;
background-color: rgba(0, 0, 0, 0.05);
border: 1px solid rgba(0, 0, 0, 0.12);
color: rgba(0, 0, 0, 0.75);
line-height: 1;
}

        .last-updated-component svg {
          flex-shrink: 0;
          vertical-align: middle;
        }

        .last-updated-component span {
          display: inline-flex !important;
          align-items: center !important;
          line-height: 1 !important;
        }

        [data-theme="dark"] .last-updated-component {
          background-color: #3a3a3a;
          border: 2px solid #888888;
          color: #ffffff;
        }

        [data-theme="dark"] .last-updated-component svg {
          stroke: #ffffff;
        }
      `}</style>
      <div className="last-updated-component">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="10" />
          <polyline points="12 6 12 12 16 14" />
        </svg>
        <span>
          <strong style={{
    fontWeight: 600
  }}>{label}</strong> 
          <time dateTime={date}>{date}</time>
        </span>
      </div>
    </>;
};

## Overview

To launch offsite ads for a particular platform, the marketplace grants Topsort access to required ad accounts, implements offsite event tracking, and Topsort handles the rest of the integration (for example, syncing catalog and offline events with the marketplace, validation).

Topsort runs a 2-week implementation timeline for each offsite platform (for example, Google or Meta) to ensure a successful POC launch, supported by dedicated cross-functional resources from the client:

* **Engineering:** \~1 day of effort from a marketplace engineer (integration and validation). Development can likely be completed on a single 90-minute call with Topsort engineers.
* **Ad Operations:** \~1 day of marketplace ad ops support for campaign setup, QA, and launch.

## Account architecture

Automated account provisioning scales to thousands of vendors with clear budget separation and minimal manual setup. Below is the recommended account structure.

<OffsiteVendorAccountArchitectureDiagram />

### Google

* **Marketplace provides:** Access to MCC (Manager account) + MCA (Merchant Center multi-client account)
* **Topsort creates:** Vendor Google Ads accounts with required Merchant Center linking

### Meta

* **Marketplace provides:** Access to Parent Business Manager
* **Topsort creates:** Child Business Manager and ad account per vendor

### TikTok

* **Marketplace provides:** Access to TikTok Business Center / Business Manager, with permission to manage advertiser accounts and assets
* **Topsort creates:** A dedicated TikTok ad account for the Topsort offsite integration, typically one ad account for the marketplace/retailer, not one per vendor

### Snap

* **Marketplace provides:** Access to Snap Business Manager / Organization, with permission to manage ad accounts and billing/assets
* **Topsort creates:** A dedicated Snap ad account for the Topsort offsite integration, typically one ad account for the marketplace/retailer, not one per vendor

## Set up steps

### Account set up

#### Account access (marketplace)

The marketplace grants Topsort admin access to the top-level ad platform accounts required for the channels being onboarded. See [Account architecture](#account-architecture) above for the specific accounts to grant access to on each platform.

#### Account creation (Topsort)

Topsort provisions the vendor-level account structure under those marketplace containers, including any child ad accounts, business managers, or merchant center accounts needed for the integration. See [Account architecture](#account-architecture) above for what Topsort creates on each platform. The marketplace can provide Topsort with a list of vendors to enable for offsite.

### Catalog sync (Topsort)

Where catalog-based offsite formats are in scope, Topsort syncs the marketplace catalog to the offsite platform, mapping each vendor's products into the corresponding platform account structure for that vendor.

### Event tracking set up (marketplace)

The only area where the marketplace will need to do development is event tracking. To report events for offsite, use the same [`/v2/events`](/en/api-reference/events/report-events) endpoint as onsite events, passing additional parameters in the request body.

#### Opaque user ID

The same `opaqueUserId` used for onsite events should also be reused for offsite attribution. No separate offsite identifier is required. Topsort needs a persistent, privacy-safe user identifier to connect clicks and purchases across channels.

The same onsite requirements apply to offsite usage:

* **Persistence:** Should remain stable for the attribution window (typically 7–30 days).
* **Consistency:** The same user should receive the same ID across visits and channels when possible.
* **Privacy-safe:** Must not contain PII such as email, phone number, or name.

#### Click URL

The URL that the user has when they land on your site from an offsite ad click will have important query params attached.

Example click URL:

```
https://www.retailer.com/search?q=shampoo&
externalCampaignId=9d2d7d7d-5d4f-4d8e-a8d0-2d7a6f9c1234&
externalVendorId=vendor_abc123&
gclid=CjwKCAj_example123&
utm_source=google&
utm_medium=c
```

Query params:

* `gclid` — click ID attached by Google
* `externalCampaignId` and `externalVendorId` — query params containing the Topsort campaign ID and vendor ID, attached by Topsort. Should persist alongside the user attribution state for at least the duration of the attribution window (configurable 7–30 days). They should survive navigation and repeat visits so subsequent purchase events can be correctly tied back to the originating offsite ad click.

#### Reporting clicks

Send the below event when a user lands on your site from an offsite ad click. All fields are required.

```http theme={null}
POST /v2/events
```

```json theme={null}
{
  "clicks": [
    {
      "occurredAt": "2023-11-07T05:31:56Z",
      "opaqueUserId": "<string>",
      "id": "<string>",
      "entity": {
        "id": "product1",
        "type": "product"
      },
      "externalCampaignId": "<Topsort UUID>",
      "externalVendorId": "<Topsort externalVendorId>",
      "dsp_metadata": {
        "gclid": "<Google click ID>"
      },
      "channel": "offsite"
    }
  ]
}
```

#### Reporting purchases

All fields are required.

```http theme={null}
POST /v2/events
```

```json theme={null}
{
  "purchases": [
    {
      "occurredAt": "2023-11-07T05:31:56Z",
      "opaqueUserId": "<string>",
      "id": "<string>",
      "items": [
        {
          "productId": "product1",
          "vendorId": "<externalVendorId>",
          "unitPrice": 75.0,
          "quantity": 1
        },
        {
          "productId": "product2",
          "vendorId": "<externalVendorId>",
          "unitPrice": 25.0,
          "quantity": 1
        }
      ]
    }
  ]
}
```

#### Sharing events to offsite platforms

The client does not need to separately report conversion events to the offsite platform. Topsort automatically sends eligible purchase events tied to the corresponding click ID (for example, Google Click ID or GCLID) through the platform's offline Conversions API.

## Onboarding schedule

### Week 1 – Access & event tracking setup

* Grant access to required accounts
* Initiate event tracking implementation
* Sync catalog if needed to offsite platform
* Begin initial system configuration

### Week 2 – Integration & data setup

* Finish integration and begin testing
* Validate event tracking and catalog structure/quality
* Once everything is set up, validate with a live campaign and monitor performance

***

<LastUpdated date="2026-05-23" />
