CI/CD guide
Catch broken ad creatives in your pipeline - before they reach any ad platform. ad-preflight validates against IAB standards and platform requirements (Google Ads, DV360, Sizmek, Adform, and more), outputs machine-readable JSON, and uses standard exit codes.
See also: CLI guide for full command reference · Deep Audit (Pro) for --deep in pipelines · MCP setup for Cursor and AI agents
Install in CI
As a dev dependency (recommended - locked version):
npm install --save-dev @ad-preflight/cli
Or run with npx (no install needed):
npx -y @ad-preflight/cli package ./ad --json
Machine mode
In machine mode, ad-preflight writes exactly one JSON object to stdout - no banners, no progress bars, no tips. Use the exit code for pass/fail.
Machine mode activates automatically when:
- You pass
--jsonor--json=pretty - stdout is not a TTY (pipes, CI runners, headless environments)
Exit codes
| Code | Meaning | Action |
|---|---|---|
| 0 | Validation passed, ZIP created | Continue pipeline |
| 1 | Validation failed, Deep Audit failed, or runtime error | Fail the build |
| 2 | Invalid arguments or setup problem (e.g. --deep without the plugin installed, unsupported Node major) |
Fix the command / finish setup |
| 3 | Licensing: system not supported, trial already used, or license no longer active | Needs a human - see the message |
Code 3 comes from the setup commands (plugin-install, trial). package itself only
ever exits 0, 1 or 2 - a licence that refuses the Deep Audit fails the run as exit 1.
Multi-size campaigns: a size that fails validation is skipped, but the run still exits 0 if the other sizes packaged. Check
packagesSkippedin the JSON (and fail the build yourself if it isn't empty) so a dropped size can't slip through unnoticed.
Non-interactive shells
No command hangs waiting for input when there is no terminal:
package,preview- never prompt.plugin-install <token>- refuses to replace an existing license in a non-interactive shell; pass--forcewhen that is intended.recover-license <email>- the email must be passed as an argument (exits 2 otherwise).trial <token>- the token is required; request it at https://ad-preflight.com first.
JSON output
Success (exit 0):
{
"success": true,
"outputPath": "compliance_my-ad.zip",
"size": 12345,
"type": "standard",
"warnings": [],
"fixLogs": [],
"staticChecks": [ { "id": "clicktag", "label": "Click handler", "status": "pass" } ],
"staticChecksBySize": { "...": [] },
"packages": [
{ "name": "my-ad", "outputPath": "compliance_my-ad.zip", "size": 12345 }
]
}
Notes for parsers:
- Collect artifacts from
packages, not fromoutputPath. For a multi-size campaign there is one entry per size; top-leveloutputPath/sizedescribe only the first ZIP. Sizes that failed validation appear inpackagesSkippedinstead. originalZipPathis present only when--fixran (path of the pre-fix backup ZIP).deepis present only when--deepran (the Deep Audit report object).staticChecks/staticChecksBySizefeed the human report checklist - safe to ignore in CI.
Failure (exit 1):
{
"success": false,
"issues": ["Missing var clickTag", "HTTP resource detected"],
"warnings": [],
"error": "Validation failed: 2 issues found"
}
Check result.success === true and exit code 0 to confirm a pass.
Pipeline examples
Simple - fail on non-zero exit
npx -y @ad-preflight/cli package ./ad --json
# Exit code 0 = pass. That's it.
Shell script - capture output
#!/bin/sh
set -e
npx -y @ad-preflight/cli package ./ad --json > result.json
echo "Ad validation passed"
GitHub Actions
- name: Validate ad creative
run: npx -y @ad-preflight/cli package ./ad --json > result.json
- name: Check result
run: |
if [ "$(jq -r .success result.json)" != "true" ]; then
echo "::error::Ad validation failed"
jq . result.json
exit 1
fi
GitLab CI
validate-ad:
script:
- npx -y @ad-preflight/cli package ./ad --json > result.json
artifacts:
paths:
- result.json
when: always
With auto-fix in CI
npx -y @ad-preflight/cli package ./ad --fix --json > result.json
# Produces compliance_ad.zip (fixed) and ad_original.zip (backup)
# Upload compliance_ad.zip as your build artifact
Options reference
All CLI options work in machine mode. Common CI flags:
| Flag | Use in CI |
|---|---|
--json |
Machine-readable output (default: compact) |
--json=pretty |
Pretty-printed JSON (easier to read in logs) |
--fix |
Auto-fix issues and produce upload-ready ZIP |
--type amp |
Validate as AMP ad (600KB limit) |
--strict-dimensions |
Fail on non-IAB dimensions instead of warning |
--deep |
Headless browser validation (Pro license required) |