OpenProposal 3.0 JSON Schema Unofficial

Unofficial · Not an IAB Tech Lab artifact

OpenProposal 3.0, generated as JSON Schema

An unofficial JSON Schema for OpenProposal 3.0 draft 1, generated from the specification text by Postindustria, an IAB Tech Lab member. The specification remains the reference: where this site and the text differ, the text wins.

Open the type mapHow it's builtDownload the schemasRead the decisions

What generating it took

The schema files are generated. A pipeline reads the specification's markdown and, through a mapping of every field, row, and statement to a type, generates the JSON Schema 2020-12 files, the rules that JSON Schema can't express, and TypeScript, Python, and Go types. The mapping and the 45 decisions are recorded by hand, each with the specification lines it rests on. How it's built explains each step. Generating a schema means settling every point a schema needs, and the text doesn't settle all of them. It took 45 recorded decisions:

39open points filledWhere the text leaves a point open, a decision fills it. We call these gaps, and both variants fill them the same way.
6changes we proposeWhere the text or its examples settle a point, and we would write it differently. You can switch these off.
10/55places the examples fail on mainThe specification's own examples fail in 10 distinct places as written, and in 55 with our proposals, which they predate. With the open PRs, in 16 and 88.

We describe each decision, and what we ask the specification to state, in our implementation feedback on IABTechLab/OpenProposal#121 and its supporting page. Each decision also has its own page here.

How to read the two switches

The type map, the examples, and the downloads each have two switches. Together they pick one of four builds of the schemas.

mainWith the open PRs Input

main is the specification on its main branch at commit 44dfaaf.

With the open PRs is main with the 14 pull requests that were open on 2026-10-26 merged in, each at its head that day. We merged them ourselves, so the result exists on no branch upstream.

As writtenWith our proposals Variant

As written switches our 6 proposals off. Each field they change takes the form the text or its examples write, such as any string for an ID and the integers 0 and 1 for AdCOM's flags.

With our proposals switches them on. In both variants, the 39 open points stay filled by their decisions, since the text gives nothing to fall back to.

What a decision record is

A decision record is a judgment we recorded wherever the specification leaves a point open, or where we propose a change. Each record has:

  • the question it answers, and the options we weighed;
  • the answer we chose, and why;
  • the specification lines it rests on, quoted and pinned, so the record goes stale when those lines change;
  • what we ask the specification to state, so that the next revision needs no such record.

The type map links every type to the records that shape it, and every record to the lines it quotes.

Inputs

Specification: IABTechLab/OpenProposal, spec/openproposal-3.0.md.

The open PRs, in the order we merged them, each with its head:

Beside resolving conflicts, the merge made these edits:

  • moved #17's App identity block back above the § 5.2.1 that #119 adds
  • set the header of #120's rewarded-video example to § 6.7
  • added time_zone: viewer_local to the examples of #70 and #120, as #123's description asks

The 6 changes we propose

Each row is one proposal, and what the as-written variant takes instead.

RecordQuestionAs writtenWith our proposals
D-037decision 40How is the ID of a record a party mints written, so that every party compares it the same way?Any string the minting party chooses.A UUID in the RFC 9562 string form, which JSON Schema's uuid format checks.
D-039decision 41How is a two-valued flag written where § 5.2.2 copies an AdCOM 0 | 1 integer?The integers 0 and 1, as § 5.2.2, AdCOM 1.0, and OpenRTB 2.6 write them.A JSON boolean, as every other flag of the specification is.
D-040decision 42How is a length of time written where the specification or its examples write it as prose, a word, or a count of seconds?Each as the specification or its examples write it, prose for lead_time, a word for cadence and granularity, 30d for attribution_window, and integer seconds for skipafter and min_interval_s.An ISO 8601 duration in the grammar of RFC 3339 Appendix A, as hold_duration is.
D-041decision 43What does a field hold whose values are terms that the specification doesn't list?Each field takes any bare term, letters and digits joined by underscores, as the examples write them.Each field gets a named open vocabulary with the core terms the specification lists, none yet, so each accepts namespaced terms <domain>:<term> only.
D-042decision 44Is a commitment's flight start and end a calendar date, as the examples write them, or a point in time?A calendar date, YYYY-MM-DD, as the examples write it.A point in time, a Timestamp, as the offer window's valid_from and valid_until are.
D-047decision 45Do the production, measurement source, and reporting options carry an id that included[] and the pricing keys name them by?No. The options keep the members the text lists, and included[] and the pricing keys can't name them.Yes. Each of these options carries id, required, beside the members the text lists, and included[] and the pricing keys name the option by it.

The examples fail less as written because they follow the text: on main, they fail in 10 distinct places as written against 55, and with the open PRs, in 16 against 88. What still fails as written is where the examples disagree with the text, and the option names that the text gives no member for.