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

# End-to-End API Example

> End to end integration example with our APIs

export const IntegrationsCard1A = () => {
  return <>
      <style>{`
        .integrations-card-1a {
          display: flex;
          flex-direction: column;
          background-color: #f0f2f4;
          border: 1px solid rgba(0, 0, 0, 0.08);
          border-radius: 12px;
          padding: 1.25rem 1.5rem;
          gap: 0.25rem;
          color: #25253b;
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
          transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
          margin-top: 2rem;
        }

        .integrations-card-1a:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
          border-color: rgba(0, 0, 0, 0.12);
        }

        .dark .integrations-card-1a {
          background-color: #25253b;
          color: #f6f8fa;
          border-color: rgba(255, 255, 255, 0.08);
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }

        .dark .integrations-card-1a:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
          border-color: rgba(255, 255, 255, 0.12);
        }

        .integrations-card-1a-avatar-row {
          display: flex;
          margin-left: 14px;
          flex-wrap: nowrap;
        }

        .integrations-card-1a-avatar {
          width: 44px;
          height: 44px;
          border-radius: 50%;
          border: 2px solid #f0f2f4;
          margin-left: -14px;
          object-fit: cover;
          box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
          pointer-events: none;
          cursor: default;
        }

        .dark .integrations-card-1a-avatar {
          border-color: #25253b;
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        .integrations-card-1a h2 {
          margin: 0;
          line-height: 1.25;
          font-size: clamp(1.25rem, calc(0.875rem + 1.25vw), 1.75rem);
          font-weight: 700;
          letter-spacing: -0.025em;
          color: #111827;
        }

        .dark .integrations-card-1a h2 {
          color: #f9fafb;
        }

        .integrations-card-1a-subtitle {
          font-size: 0.9375rem;
          font-weight: 500;
          line-height: 1.5;
          color: #4b5563;
          margin: 0;
        }

        .dark .integrations-card-1a-subtitle {
          color: #d1d5db;
        }

        .integrations-card-1a p {
          margin: 0;
          line-height: 1.5;
          font-size: 0.875rem;
          color: #374151;
        }

        .dark .integrations-card-1a p {
          color: #d1d5db;
        }

        .integrations-card-1a a {
          color: #0500ff;
          text-decoration: none;
          font-weight: 500;
          transition: color 0.15s ease;
        }

        .integrations-card-1a a:hover {
          color: #0400cc;
        }

        .dark .integrations-card-1a a {
          color: #8280ff;
        }

        .dark .integrations-card-1a a:hover {
          color: #a19fff;
        }

        @media (max-width: 640px) {
          .integrations-card-1a-avatar {
            width: 38px;
            height: 38px;
            margin-left: -12px;
          }

          .integrations-card-1a-avatar-row {
            margin-left: 12px;
          }
        }

        @media (min-width: 1280px) {
          .integrations-card-1a p {
            font-size: 0.6875rem;
            line-height: 1.4;
            letter-spacing: -0.01em;
          }

          .integrations-card-1a h2 {
            font-size: clamp(1rem, calc(0.75rem + 1vw), 1.25rem);
          }

          .integrations-card-1a-subtitle {
            font-size: 0.75rem;
          }
        }
      `}</style>
      <div className="integrations-card-1a">
        <div className="integrations-card-1a-avatar-row">
          <img src="/images/integration-team/agustin.webp" alt="Agustin - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/amelia.webp" alt="Amelia - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/bernardita.webp" alt="Bernardita - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/borumy.webp" alt="Borumy - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/felipe.webp" alt="Felipe - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/gui.webp" alt="Gui - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/javiera.webp" alt="Javiera - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/linn.webp" alt="Linn - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/marcio.webp" alt="Marcio - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/mateus.webp" alt="Mateus - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/max.webp" alt="Max - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/rodrigo.webp" alt="Rodrigo - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
        </div>

        <h2>Need help with your Topsort integration?</h2>

        <p className="integrations-card-1a-subtitle">
          Talk to us, the integrations engineering team.
        </p>

        <p>
          Reach us via <strong>your dedicated messaging channel</strong> or at{" "}
          <a href="mailto:support@topsort.com">support@topsort.com</a>.
        </p>

        <p>
          If you're not a customer yet,{" "}
          <a href="https://www.topsort.com/book-a-demo">book a demo</a> with our
          sales team instead.
        </p>
      </div>
    </>;
};

This example demonstrates a full flow using Topsort's APIs for a sponsored product campaign with category targeting. Replace API keys and IDs with your actual credentials and values.

**Steps:**

<Steps>
  <Step title="Sync catalog">Sync your product catalog with Topsort</Step>
  <Step title="Create a campaign">Set up a sponsored product campaign</Step>
  <Step title="Send auction requests">Request auction winners</Step>
  <Step title="Track events">Report impressions, clicks, and purchases</Step>
  <Step title="Get report">Retrieve campaign performance data</Step>
</Steps>

<Note>
  * For managing products, campaigns, and reports, use an Advanced API Key
    (TSC\_...). - For auctions and events, use a Marketplace API Key (TSE\_...).
</Note>

## 1. Sync Catalog

A sample product example-product-coca-cola, from category soft-drinks is used in this example. Remember to use your Advanced API Key.

```javascript theme={null}
const apikey = "TSC_...";

const body = {
  products: [
    {
      active: true,
      categories: ["soft-drinks"],
      id: "example-product-coca-cola",
      imageURL:
        "https://intl.cokestore.com/media/catalog/product/1/6/16181_squeeze-ko-can-maria-2.png",
      name: "Coca Cola can",
      price: "9.99",
      vendors: ["coca-cola"],
    },
  ],
};

try {
  const response = await fetch(
    "https://api.topsort.com/public/v1/catalog-search-service/catalogs/products",
    {
      method: "PUT",
      mode: "cors",
      headers: {
        Authorization: `Bearer ${apikey}`,
        "Content-Type": "application/json; charset=utf-8",
      },
      body: JSON.stringify(body),
    }
  );
  if (!response.ok) {
    console.error("unexpected status: " + response.status);
  } else {
    console.log("success status: " + response.status);
  }
} catch (error) {
  console.error(error);
}
```

## 2. Create Campaign

In this example, a campaign is created to promote the product example-product-coca-cola, having a keyword trigger (soft drink). Remember to use your Advanced API Key.

```javascript theme={null}
const apikey = "TSC_...";

const body = {
  bids: [
    {
      target: {
        type: "product",
        id: "example-product-coca-cola",
      },
      triggers: [
        {
          type: "keyword",
          value: {
            matchType: "exact",
            words: ["soft drink"],
          },
        },
      ],
    },
  ],
  budget: {
    type: "daily",
    amount: 10000,
  },
  campaignType: "autobidding",
  isActive: true,
  status: "approved",
  adFormat: "listing",
  name: "An example campaign",
};

try {
  const response = await fetch(
    "https://api.topsort.com/public/v1/campaign-service/campaigns?vendor_id=demo-vendor",
    {
      method: "POST",
      mode: "cors",
      headers: {
        Authorization: `Bearer ${apikey}`,
        "Content-Type": "application/json; charset=utf-8",
      },
      body: JSON.stringify(body),
    }
  );
  if (!response.ok) {
    console.error("unexpected status: " + response.status);
  } else {
    console.log("success status: " + response.status);
  }
} catch (error) {
  console.error(error);
}
```

## 3. Send Auction Request

In this example, an auction request is created to return winners triggered by the search term "soft drink". Remember to use your Marketplace API Key.

```javascript theme={null}
const apikey = "TSE_...";

const body = {
  auctions: [
    {
      searchQuery: "soft drink",
      slots: 1,
      type: "listings",
    },
  ],
};

try {
  const response = await fetch("https://api.topsort.com/v2/auctions", {
    method: "POST",
    mode: "cors",
    headers: {
      Authorization: `Bearer ${apikey}`,
      "Content-Type": "application/json; charset=utf-8",
    },
    body: JSON.stringify(body),
  });
  if (!response.ok) {
    console.error("unexpected status: " + response.status);
  } else {
    console.log("success status: " + response.status);
  }
} catch (error) {
  console.error(error);
}
```

## 4. Tracking Events

In this example, a click on a promoted product is tracked using our API. The resolvedBidId of the winner returned by the auctions call needs to be sent in the body of the request, to guarantee correct attribution of sales. Remember to use your Marketplace API Key.

```javascript theme={null}
const apikey = "TSE_...";

const body = {
  clicks: [
    {
      id: "d0cf3f56-a719-4e02-9c88-625f965ae6e7",
      occurredAt: "2024-07-23T11:49:04+00:00",
      opaqueUserId: "71303ce0-de89-496d-8270-6434589615e2",
      resolvedBidId:
        "ChAGafmNzX5wy4sEaDnXi4iWEhABjxq1RG513IkbvRgIVcd6GhABjmiyW3t2Ur066CLC3jWVIgoKBjExMjYzNBABMPuVDw",
    },
  ],
};

try {
  const response = await fetch("https://api.topsort.com/v2/events", {
    method: "POST",
    mode: "cors",
    headers: {
      Authorization: `Bearer ${apikey}`,
      "Content-Type": "application/json; charset=utf-8",
    },
    body: JSON.stringify(body),
  });

  if (!response.ok) {
    console.error("unexpected status: " + response.status);
  } else {
    console.log("success status: " + response.status);
  }
} catch (error) {
  console.error(error);
}
```

<IntegrationsCard1A />
