A Local Services Ads lead can be disputed days after the original customer interaction. By then, the business may have changed its opening hours, adjusted its ad schedule, modified its call-routing system, or migrated its campaign into Google Ads. The call record may still exist, but the configuration surrounding that event may no longer be visible in its original state.
This creates a data engineering problem: can an agency reconstruct the conditions that existed when a lead was evaluated, rather than relying on the account's current configuration?
Google's October 2026 Local Services Ads update makes that question more relevant. Under Google's documented rules, certain unanswered calls during business hours can qualify as valid leads when the caller remains connected for more than 20 seconds. IVR behavior, call handling, business hours, and ad scheduling can affect how an interaction is evaluated. Google also applies rules to qualifying follow-up calls and subsequent interactions with the same lead. Google documents these conditions in its Local Services Help Center.
The challenge is not that these rules are impossible to understand. It is that reproducing the relevant historical context requires data that ordinary reporting systems were never designed to preserve.
For agencies managing multiple LSA accounts, this is where event sourcing, temporal databases, and audit-oriented data pipelines become useful.
The Current-State Database Problem
Most advertising dashboards emphasize the current state of an account and summarize historical outcomes. They show the business hours currently configured, the campaign's active schedule, the number of leads recorded, and the amount charged.
That model answers operational questions well. It is less effective at reconstructing past decisions.
Consider a hypothetical plumbing business with the following timeline:
| Time | Event |
|---|---|
| Monday, 5:55 PM | Business hours are configured to end at 6:00 PM |
| Monday, 5:58 PM | A customer calls and the call goes unanswered |
| Tuesday, 9:00 AM | Business hours are changed to end at 5:30 PM |
| Wednesday | The agency investigates a disputed lead |
If the agency retrieves only the current business hours, it sees a closing time of 5:30 PM. That value does not establish what the configuration was when Monday's call occurred.
The historical question is not, "What are the business hours now?"
It is, "What business-hour configuration applied at the time of the call, and what evidence establishes that?"
The distinction is fundamental to temporal data modeling.
A conventional database might store one mutable record:
CREATE TABLE business_configuration ( business_id VARCHAR(100) PRIMARY KEY, opening_time TIME, closing_time TIME, updated_at TIMESTAMP ); When the business changes its closing time, the row is overwritten. The latest value survives, but the previous state may be lost.
Adding updated_at does not solve the problem. It tells the system when the record was last changed, not what every previous version contained.
For an auditable lead system, the data model needs to preserve configuration history.
Event Time Is Not Processing Time
Distributed systems distinguish between when an event occurred and when a system received or processed it.
These timestamps can differ.
- Event time: When the customer interaction or configuration change actually occurred.
- Ingestion time: When the agency's data pipeline received the record.
- Processing time: When a job or service processed the record.
- Evaluation time: When the lead or charge status became available to the agency.
Suppose a call occurred at 5:58 PM on Monday, but the agency's reporting integration did not ingest the corresponding record until Tuesday morning. A later billing update might arrive on Thursday.
If the pipeline orders events by ingestion time alone, it can reconstruct the wrong sequence. The configuration update received on Tuesday may appear before the call record, even though the call occurred first.
A robust data model should preserve each available timestamp independently.
{ "event_type": "call_ended", "event_time": "2026-10-19T17:58:24-04:00", "ingested_at": "2026-10-20T08:02:11Z", "source": "telephony_provider", "event_id": "evt_10482" } This is an illustrative internal event, not a Google API response. The timestamps show the difference between when the call occurred and when the agency received the record.
The pipeline should retain the original source timestamp and time zone, normalize timestamps for cross-system comparisons, and record ingestion time separately. If a source does not expose the actual event time, the system should record that limitation rather than invent one.
This becomes especially important around daylight-saving transitions, time-zone changes, and businesses operating across multiple service areas.
Model Configuration as Versioned State
Event sourcing offers one way to preserve changes. Instead of storing only the latest configuration, the system records each change as an append-only event.
For example:
[ { "event_type": "business_hours_updated", "effective_from": "2026-10-01T00:00:00-04:00", "closing_time": "18:00", "version": 12 }, { "event_type": "business_hours_updated", "effective_from": "2026-10-20T00:00:00-04:00", "closing_time": "17:30", "version": 13 } ] Again, this is a proposed schema. Agencies should record changes from authoritative sources and avoid treating an internal snapshot as proof of Google's exact configuration at the time of lead evaluation.
The benefit is that the system can query historical state instead of relying on the current row.
Conceptually, the query becomes:
SELECT * FROM configuration_history WHERE business_id = :business_id AND effective_from <= :event_time AND ( effective_to > :event_time OR effective_to IS NULL ); This query assumes the history table maintains non-overlapping effective intervals. In a production implementation, interval boundaries, time zones, corrections, and concurrent changes must be handled explicitly.
There is also an important distinction between two kinds of history.
- Valid time describes when a configuration was true in the business or advertising environment.
- Transaction time describes when the agency's system learned about or stored that configuration.
A bitemporal model preserves both. It can answer questions such as:
- What business hours did the agency believe were effective when the call occurred?
- What evidence did the agency have when it first investigated the charge?
- Did the agency later receive a correction showing that the earlier record was wrong?
This is useful when configuration updates arrive late or historical data is corrected.
It does not, by itself, prove what Google's internal systems used. That requires authoritative evidence from Google or an appropriately timestamped record of the relevant configuration.
A Lead Audit Needs an Evidence Graph
Preserving configuration history is only one part of the problem. A disputed lead may depend on several events and several independent systems.
For example, the agency may have:
- A call event from a telephony provider.
- An IVR log showing whether a caller pressed a key.
- A snapshot of business hours.
- A record of the active ad schedule.
- A lead record from Google.
- A subsequent billing-status update.
These records do not necessarily share a universal identifier. The agency needs to associate them without claiming more certainty than the data supports.
A useful internal model is an evidence graph:
Call Event | +----> Telephony Record | +----> IVR Events | +----> Business-Hours Version | +----> Ad-Schedule Version | +----> Google Lead Record | +----> Billing Status | +----> Credit or Review Update The graph is an internal audit structure, not a description of Google's private billing architecture.
Each edge should record why two records are associated. A direct shared identifier is stronger evidence than a timestamp-and-phone-number match. If a relationship is inferred, the system should preserve the matching method and confidence level.
The purpose is to make every conclusion traceable to its source records.
Late-Arriving Billing Updates Require Reconciliation
A lead's initial status should not be assumed to be its final status.
Google's lead reporting can include states such as Charged, Not charged, In review, and Credited. These describe billing or lead-review outcomes, not necessarily the business's assessment of the customer's quality.
An agency that writes a single is_billable Boolean into its data warehouse risks losing important transitions.
A more flexible model records status changes as separate events:
[ { "event_type": "lead_status_observed", "lead_id": "lead_782", "status": "In review", "observed_at": "2026-10-21T12:00:00Z" }, { "event_type": "lead_status_observed", "lead_id": "lead_782", "status": "Charged", "observed_at": "2026-10-22T09:15:00Z" } ] The example is illustrative and does not imply that Google follows this exact status sequence.
A production pipeline should retain the source's status, the time it was observed, and any available effective timestamp. If the source exposes only the current status, the warehouse should not manufacture an earlier transition history.
Reconciliation jobs can then compare the latest known Google status against the agency's internal records and identify changes that require investigation.
This is where idempotency matters. If the same status update is delivered more than once, the pipeline should not create duplicate billing events. A source event ID is ideal; otherwise, a carefully designed deduplication key may be necessary.
Historical Reporting Becomes More Important During Migration
Google's transition of Local Services Ads into specialized Performance Max campaigns with pay-per-lead goals introduces a separate continuity issue.
Google states that historical LSA campaign performance reports will not transfer into Google Ads, although historical customer lead information is expected to transfer. Google advises advertisers to preserve historical performance reports before migration. See Google's migration documentation.
This does not mean all historical data disappears. It means agencies should distinguish between customer lead records and historical campaign reporting.
An internal warehouse can preserve snapshots of available reports, campaign configuration, business-hour settings, lead records, and reconciliation outcomes before and after migration. Each record should include its source platform and extraction timestamp so that analysts do not accidentally compare data with different definitions.
Migration also makes schema versioning important. If a campaign's representation changes, the warehouse should preserve the relationship between the agency's stable internal campaign identity and the platform-specific identifiers used before and after migration.
Otherwise, a change in platform representation can look like a sudden campaign disappearance, a reporting gap, or an unexplained change in performance.
What an Auditable LSA Data Pipeline Should Preserve
The objective is not to copy every available field into a giant database. It is to retain enough evidence to reconstruct what happened and explain the limits of that reconstruction.
At minimum, I would design the pipeline around five components:
- Immutable event storage: Preserve original call, configuration, lead-status, and billing records when available.
- Versioned configuration history: Store changes to business hours, ad schedules, routing configuration, and relevant campaign settings with source and effective timestamps.
- Identity and relationship mapping: Link call records, lead records, customers, and campaign identities while distinguishing verified links from inferred matches.
- Temporal reconciliation: Evaluate events using event time, preserve ingestion time, and handle late-arriving updates without overwriting history.
- Audit output: Produce a record-level explanation containing source evidence, relevant timestamps, configuration versions, observed billing status, and unresolved gaps.
A lead audit might ultimately say:
The call occurred at 5:58 PM according to the telephony provider. The available configuration snapshot shows business hours ending at 6:00 PM. The call record indicates an unanswered interaction lasting 24 seconds. Google later reported the lead as charged. The agency's records are consistent with the documented missed-call conditions, but they do not independently establish Google's internal evaluation.
That is a defensible conclusion. It distinguishes the agency's evidence from Google's final billing decision.
If the configuration snapshot was captured only after the call, or if the telephony record lacks reliable duration data, the audit should state that limitation rather than infer certainty.
The Real Problem Is Reproducibility
A dashboard can tell an agency that a lead was charged. A historical data model can help explain what was known about the interaction when it occurred.
That difference becomes critical when configuration changes, delayed status updates, and platform migrations complicate the evidence.
Google's October 2026 lead rules create concrete reasons to care about event timing and historical configuration. But the deeper engineering lesson extends beyond LSAs: whenever a billing decision depends on a sequence of events and changing rules, current-state reporting is not enough.
Event sourcing and temporal databases will not reveal Google's undisclosed internal decision logic. They can, however, make an agency's own evidence reproducible, its data gaps visible, and its billing investigations more rigorous.
The question is not just whether a lead was charged. It is whether your system can reconstruct the relevant historical state, show the evidence behind its conclusion, and clearly identify what it cannot prove.





