{
  "schema_version": 1,
  "method_version": "ad-verification-v1",
  "last_reviewed": "2026-07-18",
  "canonical_page": "https://trueproxies.com/use-cases/ad-verification/",
  "artifact_state": "blank_dictionary",
  "top_level_keys": [
    "schema_version",
    "method_version",
    "last_reviewed",
    "canonical_page",
    "artifact_state",
    "batch_plan",
    "observations",
    "batch_summary"
  ],
  "field_groups": {
    "metadata": [
      "schema_version",
      "method_version",
      "last_reviewed",
      "canonical_page",
      "artifact_state"
    ],
    "batch_plan": [
      "batch_id",
      "campaign_reference",
      "expected_market",
      "schedule",
      "declared_sample_size",
      "route_origin",
      "route_selector",
      "approved_url_origin",
      "approved_url_paths_json",
      "success_rule",
      "challenge_indicator",
      "settling_window_ms",
      "selector_observation_window_ms",
      "batch_plan_limitation_notes"
    ],
    "observation": [
      "observation_batch_id",
      "observation_id",
      "navigation_attempted_at_utc",
      "route_country_requested",
      "route_selector_notes",
      "observed_exit_reference",
      "observed_exit_country",
      "network_origin",
      "browser_name",
      "browser_version",
      "viewport_width_px",
      "viewport_height_px",
      "locale",
      "consent_state",
      "account_state",
      "requested_url",
      "final_url",
      "redirect_chain_json",
      "http_status",
      "creative_id",
      "placement_id",
      "screenshot_reference",
      "challenge_result",
      "success",
      "failure_code",
      "observation_limitation_notes"
    ],
    "batch_summary": [
      "summary_declared_sample_size",
      "summary_observed_sample_size",
      "summary_successful_observations",
      "summary_success_rate",
      "summary_challenge_tested_observations",
      "summary_challenge_observed_observations",
      "summary_challenge_test_coverage",
      "summary_challenge_rate",
      "summary_failed_observations",
      "batch_summary_limitation_notes"
    ]
  },
  "nested_field_groups": {
    "success_rule": [
      "accepted_http_status_min",
      "accepted_http_status_max",
      "required_final_path",
      "required_creative_id",
      "require_no_challenge"
    ],
    "challenge_indicator": [
      "selector",
      "attribute",
      "expected_value"
    ]
  },
  "nested_field_definitions": {
    "success_rule": [
      { "name": "accepted_http_status_min", "type": "integer", "description": "Inclusive minimum accepted final HTTP status from 100 through 599." },
      { "name": "accepted_http_status_max", "type": "integer", "description": "Inclusive maximum accepted final HTTP status from 100 through 599; not lower than the minimum." },
      { "name": "required_final_path", "type": "exact safe path", "description": "Required successful final path, predeclared in the approved safe-path set." },
      { "name": "required_creative_id", "type": "string", "description": "Optional authorized creative identifier that must match when declared." },
      { "name": "require_no_challenge", "type": "boolean", "description": "Whether success requires the declared challenge indicator to be not_observed." }
    ],
    "challenge_indicator": [
      { "name": "selector", "type": "bounded CSS selector", "description": "Optional prevalidated selector observed only inside the bounded window." },
      { "name": "attribute", "type": "safe attribute name", "description": "Optional approved attribute read from the selected element; must be paired with expected_value." },
      { "name": "expected_value", "type": "string", "description": "Expected attribute value; must be paired with attribute." }
    ]
  },
  "csv_columns": [
    "schema_version",
    "method_version",
    "last_reviewed",
    "canonical_page",
    "artifact_state",
    "batch_id",
    "campaign_reference",
    "expected_market",
    "schedule",
    "declared_sample_size",
    "route_origin",
    "route_selector",
    "approved_url_origin",
    "approved_url_paths_json",
    "success_rule",
    "challenge_indicator",
    "settling_window_ms",
    "selector_observation_window_ms",
    "batch_plan_limitation_notes",
    "observation_batch_id",
    "observation_id",
    "navigation_attempted_at_utc",
    "route_country_requested",
    "route_selector_notes",
    "observed_exit_reference",
    "observed_exit_country",
    "network_origin",
    "browser_name",
    "browser_version",
    "viewport_width_px",
    "viewport_height_px",
    "locale",
    "consent_state",
    "account_state",
    "requested_url",
    "final_url",
    "redirect_chain_json",
    "http_status",
    "creative_id",
    "placement_id",
    "screenshot_reference",
    "challenge_result",
    "success",
    "failure_code",
    "observation_limitation_notes",
    "summary_declared_sample_size",
    "summary_observed_sample_size",
    "summary_successful_observations",
    "summary_success_rate",
    "summary_challenge_tested_observations",
    "summary_challenge_observed_observations",
    "summary_challenge_test_coverage",
    "summary_challenge_rate",
    "summary_failed_observations",
    "batch_summary_limitation_notes"
  ],
  "rules": {
    "blank_state": "The public template has no observations and no measured plan or summary values.",
    "url_sanitization": "Accept only HTTP(S) URLs on the predeclared origin and exact predeclared capability-free safe paths. Remove credentials, query strings, and fragments; replace every unapproved or dynamic path with /[redacted-path] while preserving its actual HTTP(S) origin.",
    "exit_sanitization": "Keep raw exit IP evidence outside the worksheet. Store only a non-reversible reference controlled by the evidence owner.",
    "failure_retention": "Keep navigation failures as observations with success false and a bounded failure_code; never copy raw exception text.",
    "success_evaluation": "Evaluate every configured success_rule condition, require a verified globally routable IPv4 exit reference, and require observed country to match a declared country selector. HTTP status alone is insufficient.",
    "challenge_rate": "Divide observed challenges only by challenge-tested observations. Report challenge-test coverage separately.",
    "selector_window": "Optional selectors use settling_window_ms plus the recorded selector_observation_window_ms and distinguish not_observed from not_tested. Target selectors are not tested after navigation failure.",
    "screenshot_reference": "Capture only after successful target navigation into a caller-supplied absolute private directory outside the current workspace, with restrictive permissions. Set a unique nullable non-public reference only after capture succeeds; do not embed screenshot data or a public URL.",
    "route_metadata": "Declare a validated route_origin and route_selector before collection. Requested and observed countries must belong to the explicit ISO 3166-1 alpha-2 set; use unknown when no supported selector is confirmed."
  },
  "csv_serialization": {
    "encoding": "UTF-8",
    "dialect": "RFC 4180",
    "nested_values": "Serialize objects and arrays with JSON.stringify before CSV escaping.",
    "null_values": "Serialize null as an empty field.",
    "formula_safety": "Prefix values beginning with =, +, -, or @ with a single quote before CSV escaping.",
    "escaping": "Wrap fields containing commas, quotes, CR, or LF in double quotes and double each embedded quote."
  },
  "prohibited_values": [
    "Proxy credentials or endpoints",
    "Raw exit IP addresses",
    "Account identifiers or personal data",
    "Screenshot bytes or public screenshot URLs",
    "Access tokens or share capabilities",
    "Unredacted query strings or URL fragments"
  ],
  "fields": [
    { "name": "schema_version", "group": "metadata", "type": "integer", "description": "Artifact schema version." },
    { "name": "method_version", "group": "metadata", "type": "string", "description": "Version of the controlled collection method." },
    { "name": "last_reviewed", "group": "metadata", "type": "ISO date", "description": "Date the method and field contract were reviewed." },
    { "name": "canonical_page", "group": "metadata", "type": "URL", "description": "Existing canonical page that documents the method." },
    { "name": "artifact_state", "group": "metadata", "type": "enum", "description": "Blank template, blank dictionary, or locally populated observation state." },
    { "name": "batch_id", "group": "batch_plan", "type": "string", "description": "Non-sensitive identifier for the planned batch." },
    { "name": "campaign_reference", "group": "batch_plan", "type": "string", "description": "Non-sensitive campaign reference; never an account identifier." },
    { "name": "expected_market", "group": "batch_plan", "type": "string", "description": "Market declared before collection." },
    { "name": "schedule", "group": "batch_plan", "type": "string", "description": "Declared collection schedule and test window." },
    { "name": "declared_sample_size", "group": "batch_plan", "type": "integer", "description": "Observation count declared before collection." },
    { "name": "route_origin", "group": "batch_plan", "type": "enum", "description": "Validated residential_ipv4, datacenter, control, or unknown route origin." },
    { "name": "route_selector", "group": "batch_plan", "type": "ISO 3166-1 alpha-2 code or unknown", "description": "Validated assigned country selector declared before collection; unknown when unsupported or unavailable." },
    { "name": "approved_url_origin", "group": "batch_plan", "type": "HTTP(S) origin", "description": "Credential-free HTTP(S) origin predeclared for URL evidence." },
    { "name": "approved_url_paths_json", "group": "batch_plan", "type": "JSON array", "description": "Exact safe URL paths predeclared before collection; serialized as JSON in CSV." },
    { "name": "success_rule", "group": "batch_plan", "type": "JSON object", "description": "Declared status, final-path, creative, and challenge conditions; serialized as JSON in CSV." },
    { "name": "challenge_indicator", "group": "batch_plan", "type": "JSON object", "description": "Optional selector and attribute/value condition; serialized as JSON in CSV." },
    { "name": "settling_window_ms", "group": "batch_plan", "type": "integer", "description": "Bounded delay before optional selectors are observed." },
    { "name": "selector_observation_window_ms", "group": "batch_plan", "type": "integer", "description": "Bounded per-selector timeout recorded with the plan." },
    { "name": "batch_plan_limitation_notes", "group": "batch_plan", "type": "array", "description": "Known plan limitations; serialized as JSON in CSV." },
    { "name": "observation_batch_id", "group": "observation", "type": "string", "description": "Batch identifier copied into each observation." },
    { "name": "observation_id", "group": "observation", "type": "string", "description": "Unique non-sensitive identifier for one observation." },
    { "name": "navigation_attempted_at_utc", "group": "observation", "type": "ISO timestamp", "description": "UTC time captured immediately before placement navigation was attempted." },
    { "name": "route_country_requested", "group": "observation", "type": "ISO 3166-1 alpha-2 code or null", "description": "Assigned country requested through a currently available selector, or null when no country selector was declared." },
    { "name": "route_selector_notes", "group": "observation", "type": "string", "description": "Non-secret route conditions without an endpoint or credentials." },
    { "name": "observed_exit_reference", "group": "observation", "type": "string or null", "description": "Non-reversible reference to separately controlled exit evidence." },
    { "name": "observed_exit_country", "group": "observation", "type": "ISO 3166-1 alpha-2 code or null", "description": "Best-effort assigned observed exit country without a raw IP." },
    { "name": "network_origin", "group": "observation", "type": "enum", "description": "Declared residential, datacenter, control, or unknown origin class." },
    { "name": "browser_name", "group": "observation", "type": "string", "description": "Browser or automation engine name." },
    { "name": "browser_version", "group": "observation", "type": "string", "description": "Browser or automation engine version." },
    { "name": "viewport_width_px", "group": "observation", "type": "integer or null", "description": "Viewport width in CSS pixels when available." },
    { "name": "viewport_height_px", "group": "observation", "type": "integer or null", "description": "Viewport height in CSS pixels when available." },
    { "name": "locale", "group": "observation", "type": "BCP 47 tag", "description": "Configured browser locale." },
    { "name": "consent_state", "group": "observation", "type": "string", "description": "Coarse consent or cookie condition without personal data." },
    { "name": "account_state", "group": "observation", "type": "enum", "description": "Signed out, authorized test account, or not recorded; no account identifier." },
    { "name": "requested_url", "group": "observation", "type": "sanitized URL", "description": "Requested origin plus pathname without credentials, query, or fragment." },
    { "name": "final_url", "group": "observation", "type": "sanitized URL or null", "description": "Final origin plus pathname without credentials, query, or fragment." },
    { "name": "redirect_chain_json", "group": "observation", "type": "JSON array", "description": "Ordered sanitized origins and paths; serialized as JSON in CSV." },
    { "name": "http_status", "group": "observation", "type": "integer or null", "description": "Final navigation status when a response was received." },
    { "name": "creative_id", "group": "observation", "type": "string or null", "description": "Authorized publisher or campaign creative identifier." },
    { "name": "placement_id", "group": "observation", "type": "string or null", "description": "Authorized publisher or campaign placement identifier." },
    { "name": "screenshot_reference", "group": "observation", "type": "string or null", "description": "Unique access-controlled reference set only after private capture succeeds; never a path, public URL, or embedded data." },
    { "name": "challenge_result", "group": "observation", "type": "enum", "description": "Observed, not_observed, or not_tested under the declared indicator." },
    { "name": "success", "group": "observation", "type": "boolean", "description": "Result of every configured condition in success_rule." },
    { "name": "failure_code", "group": "observation", "type": "enum or null", "description": "Bounded failure category without raw exception text." },
    { "name": "observation_limitation_notes", "group": "observation", "type": "array", "description": "Observation-specific missing evidence or interpretation limits." },
    { "name": "summary_declared_sample_size", "group": "batch_summary", "type": "integer", "description": "Declared plan size copied into the summary." },
    { "name": "summary_observed_sample_size", "group": "batch_summary", "type": "integer", "description": "Successful and failed observations retained in the worksheet." },
    { "name": "summary_successful_observations", "group": "batch_summary", "type": "integer", "description": "Observations satisfying the declared success rule." },
    { "name": "summary_success_rate", "group": "batch_summary", "type": "number or null", "description": "Successful observations divided by observed sample size." },
    { "name": "summary_challenge_tested_observations", "group": "batch_summary", "type": "integer", "description": "Observations where a challenge indicator was configured and tested." },
    { "name": "summary_challenge_observed_observations", "group": "batch_summary", "type": "integer", "description": "Challenge-tested observations where the indicator was observed." },
    { "name": "summary_challenge_test_coverage", "group": "batch_summary", "type": "number or null", "description": "Challenge-tested observations divided by observed sample size." },
    { "name": "summary_challenge_rate", "group": "batch_summary", "type": "number or null", "description": "Observed challenges divided only by challenge-tested observations." },
    { "name": "summary_failed_observations", "group": "batch_summary", "type": "integer", "description": "Retained observations that did not satisfy the success rule." },
    { "name": "batch_summary_limitation_notes", "group": "batch_summary", "type": "array", "description": "Batch-level limitations; serialized as JSON in CSV." }
  ]
}
