---
name: configure-conversion-adjustments
description: >-
  Keeps Smart Bidding honest after the sale by pushing post-conversion corrections into Google Ads:
  restate a conversion's value after a partial refund or upsell, or retract it entirely after a
  cancellation, fraud, or junk lead. VigilDog executes the adjustment uploads directly
  (gads_adjust_conversions), resolves exact action names, and validates results in the adjustment
  reporting segment; the human supplies the backend/ERP export of returns and cancellations. Run it
  when returns/cancellations are material or lead quality needs pruning, and set it up as a
  recurring cadence, not a one-off. Requires transaction IDs on original conversions
  (implement-transaction-id-deduplication). Not for whole corrupted periods
  (set-up-data-exclusions), not for importing new conversions
  (set-up-offline-conversion-tracking), and adjustments cannot change custom-variable values
  (set-up-custom-variables).
---
# Conversion Adjustments (Restate / Retract)

## Purpose
Conversion tracking records the moment of sale; the business truth often changes afterward, returns, cancellations, partial refunds, disqualified leads. Adjustments push those corrections
back into Google Ads so reporting reflects net reality and Smart Bidding stops optimizing toward
customers who refund. Two operations exist: restate (change the value) and retract (remove the
conversion).

## When to run
- Return or cancellation rates are material (a few percent of orders is already worth it).
- Lead-gen wants to retract spam/junk leads so bidding stops buying them.
- Values change post-sale: partial refunds, order edits, upsells.
- OCT-imported deal values need correcting as deals evolve.
- Setting up the recurring correction cadence for an account that has none.

## When NOT to run
- A whole time window of data is corrupted (outage, duplication bug), set-up-data-exclusions;
  adjustments are per-conversion surgery, not period-level.
- The conversions to fix were never recorded, that is import work,
  set-up-offline-conversion-tracking.
- Original conversions carry no transaction id and no click id, nothing to match against; run
  implement-transaction-id-deduplication first and adjust only conversions recorded after the fix.
- You want to change a conversion's custom-variable dimension, impossible; values are fixed at
  conversion time (set-up-custom-variables).

## Prerequisites
- Active conversion actions whose original conversions carried a transaction id (order id) or
  whose click id is stored.
- Backend/ERP export of returns, cancellations, and value changes with per-record ids, dates, and
  amounts, HUMAN-supplied.
- Adjustments must land within the platform's adjustment window: roughly 55 days from the original
  conversion. Older corrections are unprocessable.
- Exact conversion action names (VigilDog fetches these; never trust retyped names).

## Procedure
1. Resolve exact action names with `gads_list_conversion_actions`; keep the exact strings for the
   upload payload. A one-character mismatch fails the row.
2. HUMAN STEP (outside VigilDog): export the correction set from the backend/ERP, every return,
   cancellation, and value change since the last run, each with order id (or click id), event
   date, and either the new net value (partial refund) or a full-cancellation flag.
3. Translate each record into an adjustment row:
   - Full cancellation / fraud / junk lead → retraction: identifier + action name + adjustment
     datetime, no value fields at all.
   - Partial refund / value change → restatement: identifier + action name + adjustment datetime +
     the new total value and currency (the value the conversion should now have, not the delta).
   - Include all corrections regardless of channel attribution: unmatched rows are ignored
     harmlessly, and pre-filtering to "Google orders" is more error-prone than letting the match
     do the work.
4. Consult `gads_policy_guardrail` before the first Google Ads write of the session. Then upload
   via `gads_adjust_conversions`, preview first (validate_only=true default), show the user the
   parsed rows split by restate/retract with totals, commit only after explicit approval.
5. Read the per-row results: applied, unmatched (id not found, or original conversion outside the
   adjustment window), or errored (format problems). Fix and re-run failures; report unmatched
   counts rather than silently dropping them.
6. Validate after processing with `gads_run_gaql_query` using the conversion-adjustment reporting
   segment: original vs adjusted vs retracted buckets should reflect the upload. Spot-check one
   known order: its adjusted value should equal the backend's net figure.
7. Establish the cadence with the user: daily for high-return ecommerce, weekly for moderate
   volume or lead gen. Each recurring run repeats steps 2-6 with the same preview → approval →
   commit gate.
8. Add two health metrics to the account's monthly review: retraction rate (should track the real
   return/cancel rate) and adjustment lag (days from conversion to correction; aim under 14).

## Decision rules
- Retraction rows must carry no value fields; a value on a retraction fails the upload. Restate
  rows must carry both value and currency.
- Speed matters: corrections within about a week of the sale influence bidding most; the hard
  ceiling is ~55 days. If the backend export cycle is monthly, shorten it.
- Either identifier works (order id or click id); order id is preferred because it is what the
  dedup setup already sends.
- Restate value = final net value of the conversion, not the refund amount. A 100 order refunded
  25 restates to 75.
- Adjusted values rewrite reporting history (originals remain visible only in the adjustment
  segment), warn the user before the first run that past-period reports will change.
- Retraction rate persistently below the known return rate → part of the pipeline is leaking
  (missing ids, late exports); investigate rather than shrug.
- Junk-lead retraction is a quality signal, not bookkeeping: pair it with reviewing which
  campaigns produced the junk.
- Duplicate corrections are safe-ish but sloppy: re-uploading an already-applied restatement to
  the same value is a no-op, but conflicting restatements resolve to the latest, keep one
  source-of-truth export rather than merging several.
- Smart Bidding under heavy retraction: if more than roughly a quarter of a campaign's
  conversions get retracted, the bidding signal is thin as well as noisy, fix lead quality at
  the targeting/offer level rather than relying on ever-larger corrections.

## Common failure modes
- Values left on retraction rows, the classic template error and an instant row failure.
- Retyped action names with different capitalization or spacing; always source from
  `gads_list_conversion_actions`.
- Batch exports run so infrequently that corrections miss the adjustment window entirely.
- Original conversions missing transaction ids, making matching impossible, fix dedup first,
  accept that pre-fix conversions are uncorrectable.
- Uploading refund deltas instead of final values, silently doubling the correction.
- One-off cleanups with no recurring schedule: the data is accurate for a week and drifts forever
  after.

## Related skills
- Run before: implement-transaction-id-deduplication (hard dependency),
  set-up-google-ads-conversion-tracking.
- Run alongside: set-up-offline-conversion-tracking (adjusting imported stages),
  set-up-cart-data-and-profit-tracking (returns correct the profit picture too).
- Escalate to: set-up-data-exclusions when the problem is a period, not individual conversions.
- Report the health metrics into: run-a-monthly-performance-review (retraction rate and
  adjustment lag belong on the monthly tracking-integrity checklist).
