SDKsJavaScript

Reference

Complete signature and types for the JavaScript SDK's unified requestAd method.


requestAd

Request an ad and render it into a target DOM element.

window.koah.requestAd(request)

Returns Promise<AdResult>.


Types

Full TypeScript signatures for the API surface. Drop these into your project for autocomplete and type-checking.

interface Dimensions {
  /** Slot's maximum rendered width in CSS pixels. */
  maxWidth?: number
  /** Slot's maximum rendered height in CSS pixels. */
  maxHeight?: number
}

type ConversationContext = {
  type: 'conversation'
  question: string
  answer?: string
  external_conversation_id?: string
}

type ArticleContext = {
  type: 'article'
  title: string
  content: string
  about?: string
}

type FeedContext = {
  type: 'feed'
  text: string
  source?: string
  description?: string
}

type StaticContext = {
  type: 'static'
}

type AdContext =
  | ConversationContext
  | ArticleContext
  | FeedContext
  | StaticContext

type PreviewFormat =
  | 'card_text_md'
  | 'card_text_sm'
  | 'card_image_md'
  | 'card_image_sm'
  | 'image_side_rail_md'
  | 'poll_md'
  | 'poll_cta_md'
  | 'expandable_md'
  | 'rabbit_hole_md'
  | 'catalog_lg'
  | 'catalog_md'
  | 'catalog_sm'
  | 'quick_pick_md'
  | 'budget_finder_md'

interface AdRequest {
  target: Element
  context: AdContext
  dimensions?: Dimensions
  experimentTag?: string
  slot?: string
  previewFormat?: PreviewFormat
  signal?: AbortSignal
  onFill?: () => void
  onNoFill?: () => void
}

interface AdResult {
  filled: boolean
  fromCache?: boolean
}

type KoahAgeRange =
  | 'unknown' | 'under-13'
  | '13-15' | '16-17' | '18-20' | '21-24' | '25-29' | '30-34' | '35-39'
  | '40-44' | '45-49' | '50-54' | '55-59' | '60-64' | '65-69' | '70-74' | '75+'

type KoahGender = 'unknown' | 'male' | 'female'

type KoahIncomeBracket =
  | 'unknown' | '0-50' | '50-100' | '100-150' | '150-200' | '200+'

declare global {
  interface Window {
    koah: {
      requestAd(request: AdRequest): Promise<AdResult>
      /** @deprecated Retired. Resolves `false`. Use `requestAd`. */
      process(...args: unknown[]): Promise<boolean>
      /** @deprecated Retired. Resolves `false`. Use `requestAd`. */
      processStaticAd(...args: unknown[]): Promise<boolean>
      /** @deprecated Retired. Resolves `false`. Use `requestAd`. */
      generateTextAd(...args: unknown[]): Promise<boolean>
      setAgeRange(range: KoahAgeRange | { min: number; max: number }): void
      setAge(age: number): void
      setGender(gender: KoahGender): void
      setIncomeBracket(bracket: KoahIncomeBracket): void
    }
  }
}

AdRequest

The single argument accepted by requestAd.

  • Name
    target
    Type
    Element
    Description

    DOM element to render the ad into. Calling requestAd again with the same target cleanly replaces any previously rendered ad in that slot.

  • Name
    context
    Type
    AdContext
    Description

    Content surrounding the ad, used for contextual matching. See AdContext. Pass { type: 'static' } for static placements.

  • Name
    dimensions
    Type
    Dimensions
    Description

    Maximum rendered dimensions of your slot. Each render format has its own width and height bounds. Koah keeps any render format that fits within maxWidth × maxHeight and picks from the remaining candidates. Both axes are optional. An omitted axis has no limit. The SDK also limits the width to the target's container and to the viewport. Without dimensions, every format that fits the container width is eligible, catalog_lg included. See Sizing for mobile and desktop for reading the slot's CSS size at request time.

    More eligible formats give more fills. Pass dimensions only when your layout limits the space, and give the maximum space available. If you pass dimensions smaller than 240 × 72, the server rejects the request. requestAd resolves { filled: false }, calls onNoFill, and logs an error in the console. See Sizing & dimensions for the interactive playground and Format Bounds for the full table.

    window.koah.requestAd({
      target: document.getElementById('ad-slot'),
      context: { type: 'conversation', question, answer },
      dimensions: { maxWidth: 480, maxHeight: 300 },
    })
    
  • Name
    experimentTag
    Type
    string
    Description

    Tag this request with an experiment variant for A/B testing. See Experiments.

  • Name
    slot
    Type
    string
    Description

    Tag this request with a registered slot name to break down reporting by placement. The slot must be registered in your publisher settings first — passing an unregistered slot rejects the request, resolving with { filled: false } and calling onNoFill. See Slots.

  • Name
    previewFormat
    Type
    PreviewFormat
    Description

    Force a specific ad format for development preview. Takes a render format name such as card_text_md or card_text_sm. Bypasses normal ad selection and returns a specimen ad in the requested format. See Preview Formats.

  • Name
    signal
    Type
    AbortSignal
    Description

    Cancel an in-flight request. See Request Cancellation.

  • Name
    onFill
    Type
    () => void
    Description

    Called when an ad is successfully served.

  • Name
    onNoFill
    Type
    () => void
    Description

    Called when no ad is available. Useful for ad mediation waterfalls.


AdContext

A discriminated union on type. context is required. Pass the shape that matches the content around the ad, or { type: 'static' } for static placements.

conversation

For user/LLM chat surfaces. Omit answer to request an ad alongside the user's question (before the LLM responds), or include it to match against the full exchange.

  • Name
    type
    Type
    'conversation'
    Description
  • Name
    question
    Type
    string
    Description

    The user's message to the LLM.

  • Name
    answer
    Type
    string
    Description

    The LLM's response. Optional.

  • Name
    external_conversation_id
    Type
    string
    Description

    Stable ID for the conversation this message belongs to. Optional.

article

For editorial and long-form content pages.

  • Name
    type
    Type
    'article'
    Description
  • Name
    title
    Type
    string
    Description

    The article title.

  • Name
    content
    Type
    string
    Description

    Article body text. Send an excerpt (500–1000 characters), not the full article.

  • Name
    about
    Type
    string
    Description

    A short description of what the article is about. Optional.

feed

For social feeds, community posts, and similar text surfaces.

  • Name
    type
    Type
    'feed'
    Description
  • Name
    text
    Type
    string
    Description

    The post or feed item text.

  • Name
    source
    Type
    string
    Description

    Origin of the post (e.g. community or author name). Optional.

  • Name
    description
    Type
    string
    Description

    Supplemental description of the post's container. Optional.

static

For placements with no surrounding content: homepages, landing pages, and sidebars.

  • Name
    type
    Type
    'static'
    Description

AdResult

The resolved value of the requestAd promise.

  • Name
    filled
    Type
    boolean
    Description

    true if an ad was served and rendered into the target.

  • Name
    fromCache
    Type
    boolean
    Description

    true if the response was served from Koah's backend cache rather than freshly ranked. Present only when filled is true.


Format Bounds

See Ad formats for the sizing model. The table below gives the exact pixel bounds of each render format. Pass these names to previewFormat. The suffixes _sm, _md, and _lg mean small, medium, and large.

Render formatmin_widthmax_widthmin_heightmax_height
card_text_md240px768px200px250px
card_text_sm240px384px72px112px
card_image_md240px384px250px250px
card_image_sm240px384px72px112px
image_side_rail_md652px880px250px250px
poll_md288px768px—400px
poll_cta_md288px768px—460px
expandable_md288px768px—400px
rabbit_hole_md320px768px—400px
catalog_lg328px768px—600px
catalog_md300px768px250px250px
catalog_sm300px768px—240px
quick_pick_md300px600px250px250px
budget_finder_md300px480px300px440px

The minimum slot for any format is 240px wide × 72px tall. If you pass dimensions smaller than 240 × 72, the server rejects the request. requestAd resolves { filled: false }, calls onNoFill, and logs an error in the console.

A previewFormat must fit the slot. Without dimensions, the SDK checks it against 1440 × 550. A catalog_lg preview needs dimensions with maxHeight of 600 or more. Otherwise requestAd throws an error.


Retired methods

The v1 methods process(), processStaticAd(), and generateTextAd() are retired. Each one resolves false, calls onNoFill once, makes no request, and warns once in the console.

Retired methodrequestAd context type
process()conversation
processStaticAd()static
generateTextAd()conversation, article, or feed

See the migration guide for each call.


Request Cancellation

For single-page applications, cancel in-flight ad requests when users navigate away using AbortSignal:

const controller = new AbortController()

window.koah.requestAd({
  target: document.getElementById('ad-slot'),
  context: { type: 'conversation', question, answer },
  signal: controller.signal,
})

// Cancel if user navigates away
controller.abort()

Common pattern for chat apps:

const requestControllers = new Map()

function switchConversation(conversationId) {
  // Cancel previous conversation's pending requests
  requestControllers.get(currentConversationId)?.abort()

  // Create new controller for this conversation
  const controller = new AbortController()
  requestControllers.set(conversationId, controller)

  window.koah.requestAd({
    target: document.getElementById('ad-slot'),
    context: {
      type: 'conversation',
      question,
      answer,
      external_conversation_id: conversationId,
    },
    signal: controller.signal,
  })
}

In React, request once per slot with a ref guard and omit signal unless you're cancelling on a real route change:

function KoahAd({ question, answer, conversationId }) {
  const slotRef = useRef(null)
  const requested = useRef(false)

  useEffect(() => {
    // Assumes the SDK script has loaded — see Installation for gating on
    // `window.koah` (or load the script with `defer` instead of `async`).
    if (requested.current || !slotRef.current || !window.koah) return
    requested.current = true

    window.koah.requestAd({
      target: slotRef.current,
      context: {
        type: 'conversation',
        question,
        answer,
        external_conversation_id: conversationId,
      },
    })
    // No abort here: doing so would cancel the request under Strict Mode.
  }, [question, answer, conversationId])

  return <div ref={slotRef} />
}

Theme tokens

Set these on the theme object (window.koah_init.theme before load, or window.koah.theme at runtime) — see Appearance for usage.

TokenTypeDefaultDescription
colorScheme'light' | 'dark'auto-detectColor palette. Defaults to the user's system preference via prefers-color-scheme.
presentationMode'borderless' | 'card''card'card adds a border and surface background. borderless blends into the host page.
accentColorstring'#0d0d0d'Brand color used for CTA buttons and interactive highlights.
fontFamilystring'inherit'CSS font-family. 'inherit' uses the host page's font.
maxWidthstring'600px'Maximum width of the ad container.

Tokens apply consistently across every ad format and are forward-compatible with new formats.

Age range buckets

Strings accepted by setAgeRange for visitor attributes:

under-13<13
13-1513–15
16-1716–17
18-2018–20
21-2421–24
25-2925–29
30-3430–34
35-3935–39
40-4440–44
45-4945–49
50-5450–54
55-5955–59
60-6460–64
65-6965–69
70-7470–74
75+75+

Gender values

Strings accepted by setGender for visitor attributes:

maleMale
femaleFemale

Income brackets

Strings accepted by setIncomeBracket for visitor attributes. Values are annual household income in thousands of USD:

0-50$0–$50k
50-100$50–$100k
100-150$100–$150k
150-200$150–$200k
200+$200k+
Was this helpful?