Livery Server-driven Remote Compose templates GitHub

Interactive ads#

In one line: your ad server answers a placement with a template reference and the ad's data; Livery draws exactly that creative with that data, or nothing at all.

How it fits#

1. The contract#

{
  "id": "ads/banner", "major": 1, "dataSource": "Decision",
  "inputs": {
    "headline": { "type": "string", "required": true, "maxLength": 40 },
    "cta":      { "type": "string", "required": true, "maxLength": 18 },
    "hero":     { "type": "image", "required": true }
  },
  "actions": { "click": { "kind": "open-url", "args": { "url": { "type": "string", "required": true } } } }
}

2. Publish the creatives#

Each creative is a design (ads-hero-v3) with a template per surface you serve. Mark them "install": "OnDemand", so they download when first decided, not with every refresh.

If a partner publishes creatives, give them their own key and trust it only for ads/:

TrustedKey("partner-1", partnerPub, contractPrefixes = setOf("ads/"))

3. The decision your server returns#

{
  "placement": "feed.inline-1",
  "decisionId": "d-7f3a",
  "template": { "designId": "ads-hero-v3" },
  "data": { "headline": "Winter sale", "cta": "Shop now", "hero": "https://cdn.adnet.example/w.jpg" },
  "tracking": { "impression": ["https://t.adnet.example/i?d=7f3a"], "click": ["https://t.adnet.example/c?d=7f3a"] }
}

Pin "sha256" instead of designId to serve one exact blob. Validate data on the server with the same contract before answering.

4. Draw it#

val decision = adServer.decide("feed.inline-1")                // your call; returns a Decision
LiverySlot(key = decision?.decisionId, host = host, fallback = { /* nothing */ }) {
  if (decision == null) PlanResult.Fallback("no fill")
  else planner.forDecision(TemplateQuery("ads/banner@1", inApp, widthDp = 360), decision)
}

Impression fires after the first frame and Viewable after an unbroken second at least half on screen; route them, and the decision's tracking URLs, through your EventSink.

5. Images#

Ad images are remote. Serve them through an image proxy declared in the catalog, so the device talks to one host you trust, never the advertiser's. See Images and fonts.

Deployment checklist#

Edit this page