Docs

CLI and library

The tester is the RTBlint Rust core compiled to WebAssembly. The same core runs as a command-line tool and as a Rust library, so a check you see in the browser is the check you can gate a build on.

CLI

Validate a bid request from a file or from stdin:

# validate a file
rtblint validate request.json

# validate from stdin
cat request.json | rtblint validate --stdin

# pin a specific tracked version
rtblint validate request.json --version 2.6-202505

# machine-readable output for CI
rtblint validate request.json --format json

# sellers.json / ads.txt against a local cache
rtblint validate --resolve --cache ./supply-cache request.json

# captured NDJSON stream: rule frequencies
rtblint validate --summary bids.ndjson

# one result per payload, then the totals
rtblint validate --batch --summary bids.ndjson

# Google Authorized Buyers protocol extras
rtblint validate --profile google-ab google-request.json

# Prebid Server /openrtb2/auction extras
rtblint validate --profile prebid-server pbs-auction.json

# Microsoft Monetize outgoing extras
rtblint validate --profile xandr xandr-request.json

# Magnite xAPI identity fields
rtblint validate --profile magnite magnite-request.json

The JSON output carries the same shape as the tester: a valid flag and an issues array, each issue with an id, severity, message, and path. Match on the id to fail a pipeline on errors while letting warnings through.

--resolve --cache <dir> checks each SupplyChain payment hop against that domain's sellers.json and the publisher's ads.txt or app-ads.txt. The cache is a local directory: sellers/<asi>/sellers.json, ads/<domain>/ads.txt, app-ads/<bundle>/app-ads.txt. Nothing is fetched.

--batch lints one JSON object per line from a file or stdin. --summary prints how often each rule id fired across that stream. --summary bids.ndjson is the histogram; --batch --summary is one line per payload plus the totals.

--profile google-ab applies Google Authorized Buyers' documented protocol extras on top of the spec: at: 3 (FIXED_PRICE) is a valid auction type, and each Imp must carry ext.billing_id. --profile prebid-server applies Prebid Server /openrtb2/auction extras: each Imp must name a bidder or stored request, and wseat/bseat are refused. --profile xandr requires ext.appnexus.seller_member_id and video ext.appnexus.context. --profile magnite requires Magnite xAPI identity fields. The flag is refused on ARTF payloads. Floors, blocklists, and other business policy stay out.

Rust library

Use rtblint-core to validate in-process, with no subprocess:

use rtblint_core::validate;

let result = validate(&bid_request_json);
if !result.valid {
    for issue in &result.issues {
        eprintln!("{} [{}] {}", issue.severity, issue.id, issue.message);
    }
}

validate targets the latest tracked 2.6 snapshot; validate_bid_request_for_version pins a specific one. validate_bid_request_with_profile applies an exchange profile (Profile::GoogleAuthorizedBuyers, Profile::PrebidServer, Profile::Xandr, Profile::Magnite) on top of the spec.

Node / npm library

For JavaScript and TypeScript, rtblint-core is the same validator compiled to WebAssembly, with no native dependency to build:

npm install rtblint-core
import { validate, validateResponse, versions } from "rtblint-core";

const report = validate(JSON.stringify(bidRequest));          // latest tracked 2.6
const legacy = validate(JSON.stringify(bidRequest), "2.5");   // version-aware
const response = validateResponse(JSON.stringify(bidResponse));

if (!report.valid) {
  for (const issue of report.issues) {
    console.log(`[${issue.severity}] ${issue.path}: ${issue.message} (${issue.id})`);
  }
}

Findings carry the same stable rule id, severity, message, and JSON path as the tester and the CLI. validateDialect covers protobuf JSON; validateProfile applies an exchange profile such as google-ab, prebid-server, xandr, or magnite.

Packages

  • rtblint: the Rust CLI (crates.io)
  • rtblint-core: the Rust validation library (crates.io)
  • rtblint-core: the WASM-backed npm library for Node (npm)
  • rtblint-mcp: the stdio MCP server crate (crates.io)
  • GitHub Action: uses: aleksUIX/rtblint@<tag>

A hosted MCP server also runs at rtblint.org/mcp. Native Go and Python bindings are on the roadmap; track progress on GitHub.

Start from the bid request tester to see the output, then wire the same checks into your pipeline.