moqAdmoqad.dev Sandbox

colorbars.dev

Drop-in decision and beacon sink

Matches cue spec v1 from colorbars draft PR 441 (323f55a). The player kit exports AdDecisionFn and a sink for all 11 events.

Broadcasts

Next to the program, publish two more broadcasts. If the program is demo/program.hang, the cue broadcast is demo/ads.hang and the ad media broadcast is demo/ad.hang. The catalog section is adInsertion.

{
  "adInsertion": {
    "version": 1,
    "track": "ads",
    "program": "program.hang",
    "ad": "ad.hang",
    "groupDurationMs": 2000
  }
}

Cue record

One JSON object on the ads track, carried with @moq/json. Types are cue-out, cue-in, and cancel.

{
  "v": 1,
  "type": "cue-out",
  "breakId": "brk_2130706456",
  "eventId": 2130706456,
  "seq": 4,
  "durationMs": 30000,
  "splice": { "group": 1842, "wallMs": 1762800000000, "pts": 1620000 },
  "scte35": "…base64 splice_insert…",
  "autoReturn": true,
  "source": "manual",
  "issuedAtMs": 1762800000000
}

Decision

AdDecisionFn(breakId, durationMs, context) returns the creatives. An empty array means stay on the program. moqAdDecision({ baseUrl }) is that function.

import { moqAdDecision, moqAdBeaconSink } from "@moqad/sdk";

const decide = moqAdDecision({ baseUrl: "https://moqad.dev" });
const sink = moqAdBeaconSink({ baseUrl: "https://moqad.dev", sessionId });
const creatives = await decide(breakId, durationMs, context);

The HTTP body is the same three arguments. The response is { creatives, decisionId, eventId, breakId, beaconUrl, demo }. The function returns creatives only, which is what the fixture returned.

Eleven events

adBreakStart, adStart, impression, firstQuartile, midpoint, thirdQuartile, complete, click, skip, adBreakEnd, error. Each one includes eventId and creativeId. Send them to POST /v1/beacon.

moqAd is a product of BitPrairie LLC. Sandbox payments only. Choosing an ad uses the prices, dates, and limits on the campaign. It does not use SI (Super Intelligence).