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

# Ejemplo de API de extremo a extremo

> Ejemplo de integración de extremo a extremo con nuestras APIs

export const IntegrationsCard1AEs = () => {
  return <>
      <style>{`
        .integrations-card-1a-es {
          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-es:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
          border-color: rgba(0, 0, 0, 0.12);
        }

        .dark .integrations-card-1a-es {
          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-es:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
          border-color: rgba(255, 255, 255, 0.12);
        }

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

        .integrations-card-1a-es-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-es-avatar {
          border-color: #25253b;
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        .integrations-card-1a-es 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-es h2 {
          color: #f9fafb;
        }

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

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

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

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

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

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

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

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

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

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

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

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

          .integrations-card-1a-es-subtitle {
            font-size: 0.75rem;
          }
        }
      `}</style>
      <div className="integrations-card-1a-es">
        <div className="integrations-card-1a-es-avatar-row">
          <img src="/images/integration-team/agustin.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/amelia.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/bernardita.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/borumy.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/felipe.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/gui.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/javiera.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/linn.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/marcio.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/mateus.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/max.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
          <img src="/images/integration-team/rodrigo.webp" alt="" loading="lazy" className="integrations-card-1a-es-avatar" />
        </div>

        <h2>¿Necesitas ayuda con tu integración de Topsort?</h2>

        <p className="integrations-card-1a-es-subtitle">
          Habla con nosotros, el equipo de ingeniería de integraciones.
        </p>

        <p>
          Contáctanos a través de <strong>tu canal de mensajería dedicado</strong> o en{" "}
          <a href="mailto:support@topsort.com">support@topsort.com</a>.
        </p>

        <p>
          Si aún no eres cliente,{" "}
          <a href="https://www.topsort.com/book-a-demo">agenda una demo</a> con nuestro
          equipo de ventas.
        </p>
      </div>
    </>;
};

Este ejemplo demuestra un flujo completo utilizando las APIs de Topsort para una campaña de productos patrocinados con segmentación por categoría. Reemplaza las claves de API e IDs con tus credenciales y valores reales.

**Pasos:**

<Steps>
  <Step title="Sincronizar catálogo">Sincroniza tu catálogo de productos con Topsort</Step>
  <Step title="Crear una campaña">Configura una campaña de productos patrocinados</Step>
  <Step title="Enviar solicitudes de subasta">Solicita ganadores de subasta</Step>
  <Step title="Rastrear eventos">Reporta impresiones, clics y compras</Step>
  <Step title="Obtener reporte">Recupera datos de rendimiento de la campaña</Step>
</Steps>

<Note>
  * Para gestionar productos, campañas y reportes, usa una Advanced API Key
    (TSC\_...). - Para subastas y eventos, usa una Marketplace API Key (TSE\_...).
</Note>

## 1. Sincronizar Catálogo

Un producto de ejemplo example-product-coca-cola, de la categoría soft-drinks es usado en este ejemplo. Recuerda usar tu 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. Crear Campaña

En este ejemplo, se crea una campaña para promover el producto example-product-coca-cola, con un disparador de palabra clave (soft drink). Recuerda usar tu 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. Enviar Solicitud de Subasta

En este ejemplo, se crea una solicitud de subasta para devolver ganadores activados por el término de búsqueda "soft drink". Recuerda usar tu 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. Rastreo de Eventos

En este ejemplo, se rastrea un clic en un producto promovido usando nuestra API. El resolvedBidId del ganador devuelto por la llamada de subastas debe enviarse en el cuerpo de la solicitud, para garantizar la atribución correcta de ventas. Recuerda usar tu 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);
}
```

<IntegrationsCard1AEs />
