SDKs
AI
CopilotKit
Getting Started
Add Adzen to CopilotKit

Add Adzen to CopilotKit

Use this guide when you already have a CopilotKit app and want Adzen to deliver contextual ads alongside assistant messages.

Adzen operates as AG-UI middleware. It does not wrap or modify the CopilotKit runtime — it processes the AG-UI event stream and adds adzen_placement custom events when an ad matches the assistant output.

Prerequisites

  • A working CopilotKit app with an AG-UI-compatible backend agent
  • @copilotkit/react-core and @copilotkit/runtime
  • Node.js >=18
  • Adzen API key

Step 1: Install Packages

npm install @adzenai/ai @adzenai/core

Or with pnpm:

pnpm add @adzenai/ai @adzenai/core

Step 2: Configure Environment

Add these variables to your .env:

ADZEN_API_KEY=your_api_key

Step 3: Add Middleware to the AG-UI Event Stream

Instantiate AdzenAsyncMiddleware and pipe every AG-UI event through processEvent(). The middleware passes all events through unchanged and appends adzen_placement custom events when an ad is returned.

Where you place this depends on your architecture:

Option A: Server-side (in your CopilotKit runtime route or AG-UI agent)

import { AdzenAsyncMiddleware } from "@adzenai/ai/copilotkit";
 
const adzen = new AdzenAsyncMiddleware({
  apiKey: process.env.ADZEN_API_KEY!,
});
 
// In your AG-UI event processing loop:
for await (const event of upstreamEvents) {
  const downstream = await adzen.processEvent(event);
  for (const evt of downstream) {
    sendToClient(evt);
  }
}

Option B: Client-side (processing events as they arrive from the CopilotKit runtime)

import { AdzenAsyncMiddleware } from "@adzenai/ai/copilotkit";
 
const adzen = new AdzenAsyncMiddleware({
  apiKey: "your_api_key",
});
 
// In your event handler:
async function handleAgUiEvent(event: Record<string, unknown>) {
  const downstream = await adzen.processEvent(event);
  // Process all downstream events (original + any ad placements)
  for (const evt of downstream) {
    processEvent(evt);
  }
}

Step 4: Bridge Events to React

On the client, use dispatchPlacementEvents() to bridge AG-UI adzen_placement events to browser CustomEvents that the React components listen for:

import { dispatchPlacementEvents } from "@adzenai/ai/copilotkit/react";
 
// After processing events through the middleware:
dispatchPlacementEvents(downstream);

This must run in a browser environment. Non-placement events are silently ignored.

Step 5: Render Ad Cards

Add <AdzenCard> below each assistant message in your chat UI:

import { AdzenCard } from "@adzenai/ai/copilotkit/react";
 
function MessageList({ messages }) {
  return (
    <>
      {messages.map((msg) => (
        <div key={msg.id}>
          <MessageBubble content={msg.content} role={msg.role} />
          {msg.role === "assistant" && (
            <AdzenCard messageId={msg.id} />
          )}
        </div>
      ))}
    </>
  );
}

AdzenCard returns null when there is no ad for the given messageId, so it is safe to render unconditionally after every assistant message.

Step 6: Verify a Live Request

Send a message through your CopilotKit UI, then verify:

  1. The assistant response streams normally with no added latency.
  2. After the message completes, an ad card appears below it (if the Adzen API returned a match).
  3. The ad card displays a headline, description, CTA, and optional creative image.
  4. After the card is visible for 1 second (default viewability threshold), an impression beacon fires.
  5. Check your Adzen dashboard for the impression event.

If the Adzen API returns no_match or is unreachable, no ad card appears and the assistant experience is unaffected.

Next Steps