Vendor · engineers · marketers
src, type, cat, and a unique ord
Campaign Manager tags look like path soup. They are still URLs with a contract. A leftover ord=1 is a live undercount. gdpr_consent=1 is a live non-consent.
Identity of the activity
Floodlight parameters ride on the path as semicolon-delimited pairs, not a query string. /ddm/activity/src=123;type=conv;cat=purch;ord=987 is the shape. Host: doubleclick.net. src is the numeric Floodlight configuration ID (advertiser). type is the activity group tag. cat is the activity tag. Trafficking the wrong cat is a silent wrong conversion, not a 404. Pixellint: vendor.floodlight.param.src.missing, .type.missing, .cat.missing, plus empty and invalid variants.
The pack page /packs/floodlight/ is the path table. This playbook is trafficking plus consent. There is no CAPI twin with a different clock. The image or iframe is the pipe. Server-to-server Floodlight exists as a different Campaign Manager feature; if you use it, still keep src, type, and cat honest. Staging must use a staging cat so QA purchases do not land on the production activity.
https://ad.doubleclick.net/ddm/activity/src=1234567;type=conv;cat=purch;ord=987654321;qty=1;cost=19.99
pixellint validate url @floodlight.txt --rulepack vendor/floodlight
ord and unique counting
ord is required cache busting. Unique counting sends ord=1 together with a random num. Pixellint: vendor.floodlight.counting.unique_requires_ord when num is present without ord. A leftover ord=1 on a standard counter tag collapses fires into one cached GET. Do not put PII in ord. An unexpanded [CACHEBUSTER] on a fired URL failed at serve time.
Macros from GAM have to expand. Fired URLs still containing [CACHEBUSTER] are undercounts. Validate as fired, not as template, when the tag already served. A literal 1 that you copied from a screenshot is the classic production miss.
IAB consent on the path
gdpr, gdpr_consent, gpp, gpp_sid, and us_privacy ride as the same semicolon fields. Core privacy rules read query string and Floodlight-style path parameters. That is why TCF, GPP, and US Privacy are core rules, not a Google-only pack. gdpr is 0 or 1. gdpr=1 needs a TC String whose first six bits decode to version 2, core segment at least 36 characters. gdpr_consent=1 and gdpr_consent=true pass an alphabet check and fail a decode. They are valid base64 and still not a TC String.
Empty values and unexpanded macros are template slots. A fired tag still containing an unexpanded GDPR consent token never carried consent. Duplicate gdpr_consent parameters are core.privacy.duplicate_signal. Floodlight on the same page as Consent Mode still wants the TC String on the tag. Consent Mode is not TCF.
https://ad.doubleclick.net/ddm/activity/src=1234567;type=conv;cat=purch;ord=1;num=9988;gdpr=1;gdpr_consent=CPXXXXXXXX
Clock, hashing, event_id
Floodlight is not Meta CAPI. There is no event_time digit count and no SHA-256 em field on the standard activity tag. Do not hash the path. Do not invent an event_id query because a CAPI playbook said so. Cache-busting (ord / num) is the identity of the fire. Dedup is the activity's counting method in Campaign Manager, not a shared UUID with a pixel.
Cost and qty on purchase activities are still numbers you defined in CM. A currency symbol in cost is not a number. A tag sitting in Campaign Manager is a template. A HAR from a real impression is fired. Tell pixellint validate url which state you pasted. Mixed [NAME] and other macro families in one URL is a mixed-syntax finding in core.
Independence
Pixellint is not affiliated with Google or Campaign Manager. src, type, cat, ord on the path, IAB on the path, unique counting with num plus ord=1. Pack pages under /packs/floodlight/ and /packs/core/ are the contracts. This playbook is how not to traffic a click URL as an impression, and how not to ship gdpr_consent=1.
Confirm Network after publish. GTM preview is not the published container. A Floodlight tag in preview with an unexpanded consent macro will look populated in the panel and fail on the wire for everyone else. pixellint validate url --rulepack vendor/floodlight and again with core.
pixellint validate url @floodlight.txt --rulepack vendor/floodlight
pixellint validate url @floodlight.txt --rulepack core
Check the artifact
Paste the pixel URL or JSON body into the
playground. Same engine as
pixellint validate. Nothing leaves the tab.