Guides
How to validate an OpenRTB bid request
Paste the request into the bid request tester or run rtblint validate request.json. Either way you get the same findings: parse errors, missing required fields, type mismatches, unknown or moved fields, and enum values the spec does not document. This guide walks through both paths and shows how to read the output.
What validation catches
An OpenRTB bid request is one JSON object, and most of the ways it goes wrong are mechanical. A validator checks the payload against a tracked snapshot of the spec and reports, in rough order of severity:
- Malformed JSON. The payload does not parse, or parses to something other than a single object at the root. Nothing else can be checked until this is fixed.
- Missing required fields. OpenRTB 2.6 requires
id(the request ID) andimpwith at least oneImpobject. EachImpin turn needs its ownid. - Type mismatches.
atis an integer (auction type, default 2), not the string"2".tmaxis an integer of milliseconds.imp[].bidflooris a float. - Unknown fields. A key the selected version does not define, usually a typo like
bidfloror an exchange-specific field placed outsideext. - Deprecated and moved paths.
imp.video.placementwas deprecated in favor ofplcmtin the 2.6-202303 update, andregs.ext.gdprbecameregs.gdprin 2.6. See placement vs plcmt for the first case. - Out-of-range enum values. Since 2.6 the enumerated lists live in AdCOM 1.0.
atallows 1, 2, or exchange-specific values of 500 and above; a bare 9 is invalid. The enums reference collects the lists that matter for requests.
Validate in the browser
- Open the bid request tester. It is the rtblint Rust core compiled to WebAssembly, so validation runs entirely client-side and the payload never leaves your browser.
- Paste the bid request JSON, or start from the built-in sample.
- Pick the spec snapshot to validate against. The default is the latest tracked 2.6 release (2.6-202505); older snapshots exist because behavior changed between them, as the version reference documents.
- Read the findings list. Errors mean the request violates the spec; warnings mean it parses but carries something deprecated or inadvisable.
Validate with the CLI
The same core ships as a Rust CLI:
cargo install rtblint # validate a file rtblint validate request.json # validate from a pipe cat request.json | rtblint validate --stdin # pin a spec snapshot rtblint validate request.json --version 2.6-202505 # machine-readable output rtblint validate request.json --format json
The exit code is 0 when the request is valid (warnings allowed), 1 when it has errors, and 2 on usage or I/O problems, so it drops straight into scripts. See OpenRTB validation in CI for a GitHub Actions setup and the CLI docs for the library API.
Reading a finding
Every finding has three load-bearing parts:
- Rule ID, such as
openrtb.field.moved: a stable name for the class of problem, suitable for grepping or gating. The rule catalog lists them all. - JSON path, such as
imp[0].video.placement: exactly where in the payload the problem sits. - Severity:
error(spec violation) orwarning(legal but deprecated or risky).
A worked example
This request has three problems that show up constantly in the wild:
{
"id": "req-83f1",
"at": "2",
"imp": [
{
"id": "1",
"video": { "mimes": ["video/mp4"], "placement": 1 }
}
],
"regs": { "ext": { "gdpr": 1 } }
}rtblint reports, against 2.6-202505:
FAILED (OpenRTB 2.6-202505): 2 error(s), 1 warning(s). - [error] at: at expects integer but received string. (openrtb.type.mismatch) - [warning] imp[0].video.placement: imp.video.placement is deprecated in OpenRTB 2.6-202505. (openrtb.field.deprecated) - [error] regs.ext.gdpr: regs.ext.gdpr moved in OpenRTB 2.6-202505; use regs.gdpr. (openrtb.field.moved)
The fixes: send "at": 2 as an integer, replace placement with plcmt, and move the GDPR flag to regs.gdpr. Requests like this often still get parsed by lenient bidders, which is exactly why the mistakes survive: they fail selectively, on the partners that enforce types, and those partners simply stop bidding.
FAQ
What makes an OpenRTB bid request invalid?
Anything that breaks the published spec: JSON that does not parse, a root that is not a single object, a missing required field (id, or the imp array with at least one Imp object), a wrong type such as at sent as a string, a field at a path the selected version does not define, or a value outside a documented enum such as at = 9.
Can I validate a bid request without uploading it anywhere?
Yes. The rtblint tester runs the validator as WebAssembly in your browser. The payload is parsed client-side and never leaves the page, so production requests with user data are safe to paste.
Which OpenRTB versions can I validate against?
Rule depth is richest on the OpenRTB 2.6 snapshots (2.6-202204 through 2.6-202505). Object catalogs for undefined-field and type checks cover 2.0 through 3.0.
Validate it
Paste a request into the bid request tester to see these checks run live, client-side. For repeatable checks, cargo install rtblint and wire rtblint validate into your pipeline. The full list of what runs is in what rtblint checks.