Skip to main content

Custom GPT Integration Guide

This guide explains how to integrate the In-Chat Recommendations API into a Custom GPT experience.

It covers:

  • What a Custom GPT can and cannot do
  • Recommended architecture (client/server)
  • How to call the API with GPT Actions
  • How to render ads and report impressions correctly

1) What You’re Building

You are integrating ads (recommendations) into a chat conversation:

  1. The user chats with your Custom GPT.
  2. Your Custom GPT triggers an API call to fetch ads that match the conversation context.
  3. Your UI renders the ads as cards/links.
  4. You fire the reportServed impression pixel for displayed ads.

2) Custom GPT Capabilities (Important)

A Custom GPT can: ✅ Call external APIs via Actions
✅ Format structured output (JSON) for your UI
✅ Decide when to request ads (based on conversation context)

A Custom GPT cannot: ❌ Execute navigator.sendBeacon() directly
❌ Fire browser pixels itself
❌ Reliably access a user’s browsing environment

✅ Therefore:

  • The GPT should fetch ads
  • Your frontend (or host app) should render ads and fire pixels

Custom GPT  →  Your backend proxy  →  In-Chat Recs API
│ │
└────────→ UI renders ads + fires reportServed pixel

Why this is best:

  • Keeps key secure (not exposed client-side)
  • Allows logging, monitoring, retries
  • Enables safer filtering of keywords/categories

Option B: Custom GPT calls API directly

Possible, but only recommended if:

  • Key exposure is acceptable for your use case
  • You cannot deploy a backend proxy

4) What You Send to the API

Endpoint

Method: POST
URL:

https://mv.outbrain.com/Multivac/api/in-chat-recs

Query Parameters

ParameterRequiredDescription
keyYour API key
contentUrlURL-encoded host page (e.g., test.com)
widgetJSIdProvided by Teads (e.g., APP_12)
corsMust be true
testModeUse true in dev/testing

JSON Body

{
"keywords": ["investing", "savings", "personal finance"],
"iabCategories": ["IAB13"]
}

5) Configure a Custom GPT Action (OpenAPI Spec)

In the Custom GPT builder:

  1. Open Actions
  2. Add a new Action using an OpenAPI schema
  3. Point it at your backend proxy (recommended)

Example Action Endpoint (Proxy)

POST https://yourdomain.com/api/teads/in-chat-recs

Minimal OpenAPI Example

openapi: 3.0.3
info:
title: In-Chat Recommendations API Proxy
version: 1.0.0
servers:
- url: https://yourdomain.com
paths:
/api/teads/in-chat-recs:
post:
operationId: fetchInChatRecs
summary: Fetch in-chat ad recommendations
parameters:
- name: contentUrl
in: query
required: true
schema:
type: string
description: URL-encoded host page (e.g., test.com)
- name: testMode
in: query
required: false
schema:
type: boolean
description: Enable dev test mode
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
keywords:
type: array
items:
type: string
iabCategories:
type: array
items:
type: string
responses:
"200":
description: Recommendations response
content:
application/json:
schema:
type: object

✅ Your backend proxy should inject:

  • key
  • widgetJSId
  • cors=true

So the GPT never sees your secrets.


Your backend receives:

  • contentUrl
  • keywords
  • iabCategories
  • optional testMode

Then it calls:

https://mv.outbrain.com/Multivac/api/in-chat-recs?key=...&contentUrl=...&widgetJSId=APP_12&cors=true

✅ Benefits:

  • API key stays hidden
  • You can filter keywords to prevent sensitive data leakage
  • You can standardize contentUrl to the host domain only

7) Rendering Ads in Your UI

Your UI should render each item in documents[] as an Ad Card:

  • Clickable link (url)
  • Creative image (thumbnail_url)
  • Title (content)
  • Sponsor label (source_display_name)
  • Optional domain (target_domain)
  • Optional CTA button (cta)

Example UI pseudo-structure:

[thumbnail]
Title: content
Sponsored by source_display_name (target_domain)
[CTA button]

8) Reporting Impressions (Required)

Once ads are rendered, report impressions using the tracking URL:

  1. Read reportServed
  2. Append positions of displayed ads: &pos=X-Y
  3. Fire the pixel as GET or navigator.sendBeacon

Example

If displayed ads have pos: 0 and pos: 2:

{reportServed}&pos=0-2

Browser Pixel Example

function reportServed(reportServedUrl, displayedAds) {
if (!reportServedUrl) return;
const pos = displayedAds.map(a => a.pos).join("-");
const pixel = `${reportServedUrl}&pos=${pos}`;
navigator.sendBeacon(pixel);
}

9) Suggested Prompting Pattern for the Custom GPT

To keep behavior consistent, add instruction text like:

System/Developer Guidance

  • Extract 3–10 topic keywords from the conversation context
  • Choose 1–2 IAB categories when possible
  • Avoid personal data, names, emails, addresses, account IDs
  • Call the fetchInChatRecs action when the conversation is commercially relevant
  • Return the response in a structured format for the UI to render

Example output schema your GPT can produce:

{
"ads": [
{
"title": "content",
"image": "thumbnail_url",
"clickUrl": "url",
"sponsor": "source_display_name",
"domain": "target_domain",
"cta": "cta",
"pos": 0
}
],
"reportServed": "tracking.reportServed"
}

10) End-to-End Example Flow

  1. User asks: “Any advice for saving money?”
  2. GPT generates contextual signals:
    • keywords: ["budgeting", "savings", "personal finance"]
    • iabCategories: ["IAB13"]
  3. GPT calls Action: fetchInChatRecs
  4. UI renders 2 ads (positions 0 and 1)
  5. UI fires:
    {reportServed}&pos=0-1

11) Safety + Privacy Guidelines (Must Follow)

✅ DO:

  • Send only topic keywords
  • Avoid copying raw user chat text
  • Do not include personal identifiers in requests
  • Keep key secret (proxy recommended)

❌ DO NOT:

  • Send user names/emails/phone numbers
  • Send full chat transcripts
  • Attach user IDs, session IDs, or precise location

12) Troubleshooting

IssueCauseFix
Action failsProxy URL or schema mismatchValidate OpenAPI + endpoint
403 from partnerInvalid/missing API keyEnsure backend injects key
No ads returnedInvalid contentUrl or widgetVerify domain + APP_12
Impressions not countedPixel not fired or wrong pos formatUse &pos=X-Y for displayed ads

© 2026 Teads AI Platform. All rights reserved.