Competitor Ad Change Brief — BYOD Evidence Monitor
Pricing
from $42.50 / 1,000 delivered competitor-ad change reports
Competitor Ad Change Brief — BYOD Evidence Monitor
Compare buyer-authorized Meta, Google Ads, or LinkedIn evidence snapshots. Get one auditable competitor-ad change report with baseline truth, materiality, confidence, evidence gaps, and unsent human-review actions. No source fetching or campaign automation.
Pricing
from $42.50 / 1,000 delivered competitor-ad change reports
Rating
0.0
(0)
Developer
Tim Zinin
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
Compare buyer-owned Meta, Google Ads, or LinkedIn evidence snapshots and receive one auditable change report with materiality, confidence, explicit gaps, and unsent review actions.
Built for: Performance marketing teams, agencies, brand operators, competitive-intelligence analysts, and data teams that already have lawful ad-library exports or normalized evidence rows.
Commercial unit: one delivered competitor-ad change report. Live pricing contract: $0.05 per delivered result-found report plus the configured start event (starting at $0.005). Invalid input, source failure, non-comparable evidence, ambiguous delivery, and true replay are not newly delivered paid reports.

What you get
Competitive monitoring is often sold as collection. The expensive failure happens after collection: two exports cover different advertisers, countries, adapters, or time boundaries and a spreadsheet calls the difference a market event. Competitor Ad Change Brief — BYOD Evidence Monitor keeps that missing context attached to the result. Provide exactly one bounded source: inline normalized ad rows or an Apify Dataset ID. Also provide a stable watch ID, explicit coverage evidence, and a source contract naming the production source Actor/version, adapter, query scope, and advertiser identity. The output is decision support, not campaign control. Route material changes to a human campaign review; preserve uncertain or non-comparable observations without sending, pausing, or editing an ad. The Actor never sends a message, pauses an ad, changes a bid, edits a creative, files a complaint, or presents an inference as a platform fact.
The useful result in plain language
- One stable watch and report identity instead of an undocumented spreadsheet diff.
- Explicit baseline/current boundaries and an auditable source contract.
- Deterministic changes separated from evidence confidence and materiality.
- Negative and unchanged evidence retained when it affects interpretation.
- Data gaps and source risks stored as fields instead of hidden in prose.
- A conservative human-review action with
safeToAutomate=false. - One Dataset report for analysis and KVS
OUTPUTfor terminal workflow truth. - Replay-safe delivery and PPE evidence for one commercial report unit.
Who uses it
- Comparing periodic ad-library exports with a reproducible per-ad identity model.
- Building an internal review queue for new creatives, changed offers, landing domains, CTAs, formats, or stopped ads.
- Separating source coverage, evidence confidence, and change materiality in a warehouse or BI workflow.
- Giving an analyst a concise report while preserving the normalized evidence needed to reproduce it.
Not a fit
- Scraping Meta, Google, or LinkedIn directly; no platform collector is bundled.
- Automatic campaign changes, takedowns, outreach, bidding, or legal conclusions.
- Claiming spend, impressions, conversion, reach, ownership, intent, or performance when those facts are absent from the supplied evidence.
- Comparing snapshots whose adapter, query scope, entity identity, or coverage is not compatible. If you still need a collector, connect an approved upstream Actor or internal export first. Do not paste private account credentials into this Actor. Keeping collection separate makes the provenance and permission boundary reviewable.
Evidence-to-action workflow

- Collect the narrow advertiser cohort through a lawful source workflow.
- Normalize it into inline rows or an Apify Dataset and declare coverage evidence.
- Bind the observation to a stable watch ID and exact source contract.
- Validate identity, bounds, adapter compatibility, coverage, and source exclusivity.
- Acquire the per-watch lease so concurrent observations cannot race the baseline.
- Compare the compatible snapshot with the persisted baseline deterministically.
- Build one report with changes, materiality, confidence, gaps, and unsent actions.
- Write Dataset, settle the result event, and persist KVS
OUTPUT. - Route the report to a human analyst and keep external action outside the Actor.
How to run
The Actor validates the declared source contract, normalizes stable ad identity, obtains a per-watch lease, and compares the current compatible snapshot with the persisted baseline. A first compatible observation creates a baseline report. Later complete comparable observations can classify new, changed, stopped, or unchanged ads. Two complete absences are required before an ad becomes stopped; partial or unavailable observations never advance that missing streak. Optional BYOK explanation is commentary only and cannot change deterministic findings. Three concepts must remain separate:
| Concept | Question answered | It does not prove |
|---|---|---|
| Change | What differs between compatible observations? | Why a competitor changed something. |
| Materiality | How large is the deterministic observed difference? | Revenue, spend, conversion, or strategy. |
| Confidence | How well contract, coverage, and evidence support the classification? | Commercial importance or future outcome. |
| A report can show a material change with low confidence when coverage is weak. It can show high confidence and no important change. Store those axes in separate columns and keep every gap visible. |
Input contract
Use Try for free in Apify Console or submit the same JSON through API, Task, schedule, webhook, Make, n8n, or an MCP-enabled agent. The public Task is a bounded contract example:
{"schemaVersion": "1.0","requestId": "auto","watchId": "nike-us-demo-bootstrap","coverage": { "status": "complete", "comparable": true, "closed": true, "evidenceRef": "buyer://public-demo/coverage", "expectedRows": 1 },"sourceContract": {"productionActorId": "zinin/brand-evidence-source","productionActorVersion": "0.1.0","adapter": "google-ads","adapterVersion": "1.0.0","queryScope": { "advertiserId": "AR16735076323512287233", "country": "US" },"entityIdentity": { "advertiserId": "AR16735076323512287233" }},"rows": [{"platform": "google","advertiserId": "AR16735076323512287233","pageId": null,"adId": null,"creativeId": "CR16854540057166479361","isActive": true,"format": "IMAGE","copy": { "primaryText": "Unisex Nike Sportswear Tech Fleece", "headline": "Product Listing Ad Rendering Service", "description": "Nike Sportswear hoodie" },"cta": "Shop now","landingDomains": ["nike.com"],"media": ["https://tpc.googlesyndication.com/archive/simgad/3463432638140085355?sig=demo"],"offer": { "kind": null, "value": null, "currency": null, "code": null },"evidence": { "sourceRef": "https://adstransparency.google.com/advertiser/AR16735076323512287233/creative/CR16854540057166479361", "sourceRowId": "CR16854540057166479361" },"scrapedAt": "2026-08-06T11:03:09Z"}],"maxAds": 100,"maxTotalChargeUsd": 0.055,"analysisModel": "openai/gpt-4o-mini"}
Input responsibilities
| Area | Required discipline |
|---|---|
| Request identity | Reuse an ID for replay suppression; use a new ID for a genuinely new paid observation. |
| Watch identity | Keep one watch tied to one intended entity and query scope. |
| Source exclusivity | Provide inline rows or a Dataset ID, never both. |
| Coverage | Declare completeness, comparability, closure, and an evidence reference. |
| Source contract | Name upstream Actor/version, adapter/version, query scope, and entity identity. |
| Bounds | Keep rows, strings, media arrays, and total input inside the published limits. |
| Secrets | Put tokens in platform secrets, never Dataset evidence. |
| Strict validation prevents malformed identity, ambiguous source selection, invalid nested rows, missing coverage, and incomplete source contracts from advancing a baseline. A failed or partial observation must never become a clean zero-change result. |
Output stores
Default Dataset contains the delivered business report for tables, exports, BI, and review queues. Default Key-Value Store record OUTPUT contains authoritative terminal, source, baseline, delivery, pricing, replay, error, and bootstrap state.
Do not infer success from process exit or Dataset count alone. Read OUTPUT, verify terminal and delivery state, then read the Dataset report. This matters for bootstrap, unavailable source, non-comparable evidence, replay, and ambiguous delivery.
Core report fields
| Field | Meaning |
|---|---|
reportId / eventId | Stable identity for the delivered monitor outcome. |
watchId / entityId | Stable buyer-defined watch identity used for state and downstream joins. |
status | Baseline, complete, explicit partial, unavailable, non-comparable, or terminal delivery state. |
changes | Bounded deterministic change records with before/after evidence where available. |
materialityScore / materialityBand | Magnitude of observed changes; separate from evidence confidence. |
confidenceScore / confidenceBand | Support from compatible source contract, closed coverage, and usable evidence. |
sourceEvidence | Sanitized source references and row identities retained for review. |
dataGaps / confidenceRisks | Missing, partial, conflicting, or inferred facts that constrain interpretation. |
recommendedAction / actionPriority | Bounded human-review routing label, not an external action. |
safeToAutomate | False for campaign or business action in this product. |
unsentActions | Review suggestions carrying explicit not-sent and review-required guardrails. |
billing | Delivery and charge evidence for the single paid report unit. |
Shared decision semantics
| Field | Contract |
|---|---|
recordType | Stable semantic family for routing and schema evolution. |
entityId | Stable monitor identity, not automatically a legal or platform-owned identity. |
observedAt | Actor observation/finalization time, distinct from upstream publication time. |
firstSeenAt / lastSeenAt | Explicit evidence boundaries; never infer tenure from missing observations. |
before / after | Bounded comparable context supporting a transition. |
confidenceReasons / confidenceRisks | Facts that support or weaken the classification. |
failureType / retryable | Machine-readable handling kept separate from a successful report. |
billing | Delivery event and charge receipt attached to the result. |
Evidence and boundaries
reportId / eventId
Meaning: Stable identity for the delivered monitor outcome. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
watchId / entityId
Meaning: Stable buyer-defined watch identity used for state and downstream joins. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
status
Meaning: Baseline, complete, explicit partial, unavailable, non-comparable, or terminal delivery state. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
changes
Meaning: Bounded deterministic change records with before/after evidence where available. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
materialityScore / materialityBand
Meaning: Magnitude of observed changes; separate from evidence confidence. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
confidenceScore / confidenceBand
Meaning: Support from compatible source contract, closed coverage, and usable evidence. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
sourceEvidence
Meaning: Sanitized source references and row identities retained for review. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
dataGaps / confidenceRisks
Meaning: Missing, partial, conflicting, or inferred facts that constrain interpretation. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
recommendedAction / actionPriority
Meaning: Bounded human-review routing label, not an external action. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
safeToAutomate
Meaning: False for campaign or business action in this product. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
unsentActions
Meaning: Review suggestions carrying explicit not-sent and review-required guardrails. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
billing
Meaning: Delivery and charge evidence for the single paid report unit. Review questions: Is the value present and type-correct? Is it supported by source evidence or a documented deterministic transformation? Does its meaning remain the same after export? Would a missing value be incorrectly converted to zero, false, or unchanged? Downstream rule: Store the raw value with the observation time, source contract, confidence, and gaps. Do not overwrite it with a CRM disposition or an analyst conclusion.
Pricing
This Actor uses PPE: $0.05 per delivered result-found report plus the configured start event (starting at $0.005). The live Apify pricing panel is the source of truth for the current tier. Billing is part of the result contract:
- Validate input and reserve idempotent state.
- Build and validate a useful report without advancing baseline prematurely.
- Push the Dataset row with the configured result event.
- Verify the aggregate charge receipt for the current write.
- Advance durable delivery and baseline state only through the safe path.
- Persist final
OUTPUT, including ambiguous delivery. - Prevent a compatible replay from creating a second paid report.
The current-run receipt must prove an exact named
result-foundcounter delta of+1for the delivered report plus a valid linked aggregate receipt.eventChargeLimitReached: truecan accompany a successfully delivered final unit; it is not evidence that the unit failed. Never retry an ambiguous request blindly: reconcile the original run, Dataset, KVS, and event ledger first.
Decision routing
Route a material, adequately supported change to a human campaign review. Route an incomplete or
non-comparable observation to evidence repair, and route any delivery ambiguity to reconciliation.
Never map a change code directly to pausing, bidding, messaging, publishing, or another platform
action: the report deliberately keeps safeToAutomate:false and records every proposed action as unsent.
Integration recipes
Keep APIFY_TOKEN in an environment variable or secret store.
cURL
curl -X POST \"https://api.apify.com/v2/acts/zinin~competitor-ad-change-brief/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \--data-binary @public-task.json
JavaScript
import { ApifyClient } from 'apify-client';import input from './public-task.json' with { type: 'json' };const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('zinin/competitor-ad-change-brief').call(input);const output = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT');if (!output?.value) throw new Error('Missing OUTPUT record');const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log({ output: output.value, reports: items });
Python
import jsonimport osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])with open('public-task.json', encoding='utf-8') as handle:actor_input = json.load(handle)run = client.actor('zinin/competitor-ad-change-brief').call(run_input=actor_input)output = client.key_value_store(run['defaultKeyValueStoreId']).get_record('OUTPUT')if not output: raise RuntimeError('Missing OUTPUT record')items = list(client.dataset(run['defaultDatasetId']).iterate_items())print({'output': output['value'], 'reports': items})
Commercial playbooks
Human review queue
Key the destination by entityId and eventId. Create a task only for a delivered material change or a source/comparability issue. Include evidence, gaps, confidence, source contract, run ID, and observation time. Keep unsent actions as suggestions, never proof that action occurred.
Warehouse and BI
Store the raw report before flattening. Use separate columns for materiality, confidence, coverage, status, and recommended action. Retain a source-contract digest so analysts can exclude non-comparable history after an adapter or scope change.
Schedules
Use a cadence appropriate to source freshness. Generate a new request ID per intended observation. If a run is partial or unavailable, keep it visible and do not manufacture unchanged output.
n8n, Make, Zapier, and webhooks
Wait for terminal completion, read KVS OUTPUT, branch on explicit status, and fetch Dataset only for delivered reports. Route validation to input repair, retryable source failure to bounded retry, and delivery unknown to reconciliation.
Agents and MCP
A standard Apify MCP integration can expose the same schema-bound Actor call as a tool; this Actor does not add a separate always-on tool endpoint. Require an agent to cite source evidence, coverage, confidence risks, data gaps, and observation time. Prohibit invented spend, performance, intent, identity, legality, or causality. Preserve safeToAutomate=false.
Sources and rights
This Actor does not crawl advertising platforms. It analyzes buyer-supplied rows or a buyer-selected Dataset and records the declared upstream contract. The buyer remains responsible for lawful source access, export rights, retention, and the truth of the supplied coverage claim. Use opaque business identifiers where possible. Do not submit tokens, cookies, private dashboards, personal profiles, confidential strategy, or unnecessary personal data. Configure retention and access controls for Dataset, KVS, baselines, and exports. Technical accessibility does not establish permission to collect, retain, or resell data. Limited permissions, bounded input, deterministic normalization, and fixed source behavior reduce risk. Optional BYOK calls are fixed-endpoint, bounded, and explanation-only. Provider failure cannot erase deterministic findings or advance billing/baseline state by itself.
Honest limitations
- A reported creative change does not prove campaign strategy, spend, performance, infringement, or buyer intent.
- Source completeness is supplied by the caller and is validated structurally, not independently audited against a private ad platform account.
- Platform exports and upstream Actors may rename fields, paginate incompletely, omit removed ads, or change identifiers.
- Stopped detection requires two compatible complete absences; partial or unavailable observations are intentionally conservative.
- Optional LLM explanation may fail or be unavailable and never substitutes for deterministic changes or source evidence.
- A successful process exit is not enough; automation must read KVS
OUTPUTand reconcile Dataset and billing state. Additional boundaries: - Evidence describes the submitted observation, not the entire advertising market.
- Missing evidence is unknown, not zero.
- A source reference is a review pointer, not independent verification.
- A high-confidence factual change can still be commercially irrelevant.
- A low-confidence material-looking change requires more evidence, not faster automation.
- The Actor provides no legal, financial, investment, privacy, trademark, or platform-policy conclusion.
Operating guide
- Watch ID still represents the same advertiser and query scope.
- Source Actor, version, adapter, and adapter version are expected.
- Coverage supports the claimed comparison.
- Observation time and upstream evidence time remain distinct.
- Materiality and confidence are stored separately.
- Every material finding has evidence or an explicit gap.
- Partial and unavailable runs remain visible.
-
safeToAutomate=falseblocks external action. - Dataset delivery and PPE reconcile with KVS
OUTPUT. - Replays and retries cannot duplicate a paid report.
Troubleshooting
Dataset is empty
Read KVS OUTPUT. Input may be invalid, watch bootstrap may be pending, source may be unavailable/non-comparable, delivery may need reconciliation, or the request may be a replay. Empty Dataset is not automatically a successful no-change result.
First observation has no historical changes
That is expected when no compatible baseline exists. Preserve the explicit baseline result; never backfill invented prior state.
Too many ads look new or stopped
Verify source contract, entity identity, scope, adapter version, pagination, and coverage. Changed identifiers or incomplete exports can create false differences.
Partial run did not advance missing streaks
That is deliberate. Partial absence cannot prove an ad stopped. Use a later complete compatible observation.
Optional explanation is unavailable
Use deterministic changes and evidence. Never retry commercial delivery only to obtain prose.
Event limit was reached
Inspect the named result-found counter before and after the current report. Only an exact +1 delta plus the valid linked receipt proves settlement. Reconcile before retrying.
Happy, partial, and failure output
These examples are projections of actual Apify runs, not invented sample outcomes. Identifiers, counters, statuses, and decision values were read back from the run, Dataset, and KVS records. The first example is a healthy production comparison. The second is the exact historical canary that exposed the first-invocation bootstrap defect addressed by the current implementation. Neither example claims campaign performance or business impact.
Comparable observation delivered on production
Run 5NsVfYTVEbzAebYmf used production build wBfp3Q84KfYN9UAra. It completed SUCCEEDED, produced one Dataset report in Dataset Hlvut2KqecKUQ35n0, and stored terminal OUTPUT in KVS fHFT9knhtOYqbxrgp. The platform event ledger recorded one Actor start and one result-found. The Dataset and KVS projections agreed that one comparable Google Ads observation was processed against an existing baseline, no supported change was detected, and the baseline advanced.
{"evidenceAccepted": true,"runId": "5NsVfYTVEbzAebYmf","buildId": "wBfp3Q84KfYN9UAra","status": "SUCCEEDED","datasetId": "Hlvut2KqecKUQ35n0","keyValueStoreId": "fHFT9knhtOYqbxrgp","chargedEventCounts": {"apify-actor-start": 1,"result-found": 1},"datasetReport": {"reportId": "sha256:d0b8835c5a3632933792f66e5d6ad6bfa312f5ea1eea188fddf8f23de4e8836d","requestId": "5NsVfYTVEbzAebYmf","watchId": "nike-us-demo-bootstrap","status": "complete","baselineCreated": false,"coverage": {"status": "complete","comparable": true,"acceptedRows": 1},"changeCount": 0,"decision": {"materialityScore": 0,"confidenceScore": 90,"recommendedAction": "NO_MATERIAL_AD_CHANGE","actionPriority": "low","safeToAutomate": false}},"output": {"status": "complete","source": {"kind": "inline","coverageStatus": "complete","comparable": true,"inputRows": 1,"acceptedRows": 1,"invalidRows": 0,"truncated": false},"baseline": {"created": false,"advanced": true,"missingStreaksAdvanced": false},"delivery": {"resultEvents": 1,"chargeConfirmed": true,"ambiguous": false},"pricing": {"tier": "BRONZE","startPriceUsd": 0.00475,"resultPriceUsd": 0.0475},"errors": []}}
What this proves: a complete accepted observation can produce exactly one report, exactly one named result event, an explicit no-change decision, and an advanced compatible baseline. It does not prove that the upstream export captured every ad outside the caller-declared coverage contract, and it does not prove the absence of real-world campaign changes not represented in the supplied row.
Second accepted production comparison
Run PnwdbR8ejvmW1yQH0 used the same production build wBfp3Q84KfYN9UAra
on 12 August 2026. It completed SUCCEEDED, wrote one report to Dataset
XQHNBWSPecVczwnPW, and stored OUTPUT in KVS cmFUBQ5fLrJ0JV4nP.
The platform ledger recorded start1/result1. The accepted inline row was compared
against the compatible nike-us-demo-bootstrap baseline. The report found zero
supported changes, assigned materiality 0/none, evidence confidence 90/high,
recommended NO_MATERIAL_AD_CHANGE, retained two explicit data gaps, and kept
safeToAutomate:false. Baseline state advanced; no action was sent.
{"evidenceAccepted": true,"runId": "PnwdbR8ejvmW1yQH0","buildId": "wBfp3Q84KfYN9UAra","status": "SUCCEEDED","startedAt": "2026-08-12T05:07:46.384Z","finishedAt": "2026-08-12T05:07:50.982Z","datasetId": "XQHNBWSPecVczwnPW","keyValueStoreId": "cmFUBQ5fLrJ0JV4nP","chargedEventCounts": {"apify-actor-start": 1,"result-found": 1},"usageTotalUsd": 0.00040797649284203845,"dataset": {"rows": 1,"reportId": "sha256:5ac14b51ae70d8a206cce55dd7dee92a41642b8f0d750203feebf290138a42c5","watchId": "nike-us-demo-bootstrap","status": "complete","observedAt": "2026-08-12T05:07:50.152Z","changeCount": 0,"materialityScore": 0,"materialityBand": "none","confidenceScore": 90,"confidenceBand": "high","recommendedAction": "NO_MATERIAL_AD_CHANGE","actionPriority": "low","safeToAutomate": false,"dataGaps": ["AD_PERFORMANCE_NOT_OBSERVED", "MEDIA_CONTENT_NOT_FETCHED"]},"output": {"status": "complete","sourceAcceptedRows": 1,"baselineCreated": false,"baselineAdvanced": true,"resultEvents": 1,"chargeConfirmed": true,"ambiguous": false,"errors": []}}
This independently confirms a second accepted paid comparison on the production contract. It remains buyer-supplied evidence: the Actor did not log into Google Ads, fetch the retained source URL, measure campaign performance, or verify complete platform coverage.
Historical first-watch bootstrap failure
Run BoebFM6W1GxY7PTRe used candidate build 6cfeCwnT5Pex9jG0q. It completed SUCCEEDED but produced no Dataset row and no result event. KVS x3kak8YebUXRfYs3H reported watch_bootstrap with one verified seed and a 2,000 ms wait requirement. This was a valid lock-protocol observation but an invalid first-use product outcome: the buyer had submitted compatible evidence and the Store contract promised that the same invocation would create a baseline report.
{"evidenceAccepted": false,"runId": "BoebFM6W1GxY7PTRe","buildId": "6cfeCwnT5Pex9jG0q","status": "SUCCEEDED","datasetId": "IPmfArQ8hkKztAlsb","keyValueStoreId": "x3kak8YebUXRfYs3H","datasetRows": 0,"chargedEventCounts": {"apify-actor-start": 1,"result-found": 0},"output": {"requestId": "BoebFM6W1GxY7PTRe","watchId": "commercial115-competitor-20260811-r1-4d7c2a","status": "watch_bootstrap","baseline": {"created": false,"advanced": false,"missingStreaksAdvanced": false},"delivery": {"resultEvents": 0,"chargeConfirmed": false,"ambiguous": false},"bootstrap": {"status": "required","seedCount": 1,"retryAfterMs": 2000},"errors": [{"code": "bootstrap_required","retryable": true}]}}
The current runtime changes the orchestration without weakening the lock. When the first acquisition creates a seed, the same invocation waits only for the bounded consistency interval and attempts one reacquisition. Concurrent first invocations follow the same wait but still contend through the RequestQueue atomic lock, so at most one owner reads evidence or prepares delivery. A cleanup uncertainty, malformed seed, unavailable lock capability, or lost lease still fails closed. This historical result remains useful evidence of the defect; it is not presented as proof that the new code has already passed a cloud canary. That proof requires the separately controlled single candidate build and no-retry canary.
Field dictionary
Use this mapping when landing results in a warehouse or routing them into a review system. Preserve the full report as the audit record; flattened columns are convenience indexes, not replacements for evidence.
| Field | Operational use | Boundary |
|---|---|---|
reportId | Stable report join and reconciliation key. | Deterministic digest, not a signature. |
requestId | Current invocation and delivery-intent identity. | auto resolves from the trusted platform run ID. |
watchId | Long-lived comparison stream selected by the buyer. | Reusing it across different entities or scopes is invalid. |
observedAt | Actor report construction time. | It is not the source collection timestamp. |
comparability | Exact upstream Actor, version, adapter, scope, and entity contract. | A changed contract starts a new baseline. |
coverage | Accepted source status and row count. | Complete means caller-declared closed evidence matched; it is not independently crawled. |
changes[].changeId | Stable identifier for one supported change finding. | It reflects normalized supplied facts only. |
changes[].changeTypes | Closed list of creative, offer, CTA, format, landing, new, or stopped changes. | No intent or performance is inferred. |
decisionSummary.materialityScore | Deterministic prioritization signal. | Materiality is separate from confidence and business value. |
decisionSummary.confidenceScore | Evidence confidence under the declared coverage contract. | It is not model accuracy or source exhaustiveness. |
decisionSummary.sourceEvidence | Source-provided references and observation identifiers. | References are retained but never fetched or independently authenticated. |
decisionSummary.dataGaps | Machine-readable reasons not to over-interpret the result. | A non-empty list should remain visible downstream. |
decisionSummary.recommendedAction | Review routing code. | It is a suggestion, never an executed ad-platform action. |
decisionSummary.safeToAutomate | Automation safety switch. | It is always false for business action in this product. |
unsentActions | Human-review checklist derived from supported facts. | Every entry remains review-required and not sent. |
delivery.resultEvents | Named result units confirmed for this invocation. | Replays report zero new delivery. |
delivery.ambiguous | Manual-reconciliation flag after an uncertain push or counter. | Never blind-retry when true. |
baseline.advanced | Whether the canonical watch state moved to the delivered observation. | Partial, failed, or ambiguous observations do not advance it. |
bootstrap.status | Seed protocol state in KVS OUTPUT. | Normal first use is now completed inside one invocation; uncertain reconciliation can still surface explicitly. |
FAQ
Does this Actor log into ad platforms?
No. It is BYOD evidence analysis. Supply lawful normalized rows or a Dataset produced by your own approved collection workflow.
Why does the first run return a report instead of changes?
A stateful comparison needs a compatible baseline. The first useful observation records that baseline explicitly so later comparisons have a defensible origin.
Can an incomplete export mark an ad as stopped?
No. Missing streaks advance only on complete comparable observations, and stopped requires two such absences.
Does the AI explanation decide materiality?
No. Deterministic comparison builds the changes and materiality. BYOK explanation is optional commentary and cannot mutate the result.
Can I automatically pause a competitor campaign?
No. The Actor cannot control another advertiser and emits only unsent review actions with safeToAutomate=false.
What should I store downstream?
Keep the report ID, watch ID, observation times, source contract, evidence, confidence, gaps, changes, recommended action, run ID, and billing receipt together.
Support
For a reproducible issue, provide run ID, Actor version, sanitized input, source-contract shape, OUTPUT status, Dataset count, and whether it happened during baseline, comparison, replay, or reconciliation. Never send a token, private export, or signed storage URL.
Competitor Ad Change Brief — BYOD Evidence Monitor is intentionally conservative: it makes a bounded comparison explainable, preserves uncertainty, and routes evidence to a human. That is more commercially useful than a confident alert whose source scope, baseline, delivery, or meaning cannot be defended.