---
title: AddressVerificationService
summary: API reference for AddressVerificationService.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-24
library: SAIF.Services
reference_type: package
---

# AddressVerificationService

Implements `IAddressVerificationService`, batch-reconciling verified/CASS-corrected addresses against provider location addresses: expiring outdated provider addresses, inserting corrected replacements, and pushing the same corrections to the external Provider Data API so the legacy database and the API stay in sync. It depends on `IUnitOfWork` for repository access and transactions, `IAddressVerficationQueryProvider` and `IProviderQueryProvider` for reading verification/provider data, `IUserProfileService` for the current user, `IVerifiedAddressProviderMatchService` for field-level address comparison rules, `IEnvironmentService` (injected but not directly used in the reviewed methods), and `IProviderDataApiClient` for updating/adding provider addresses in the external API.

## Purpose
- Processes all active provider addresses updated since a given date, comparing each against its verified address and updating only those whose differences meet defined update rules.
- Expires the old provider address and inserts a corrected replacement row when an update is warranted, then mirrors that change to the external Provider Data API.
- Attempts to manually roll back the legacy database row if the external API call fails after the local update succeeded.
- Determines whether a verified address should replace a provider address using specific field-comparison rules (address line, city, state, zip) and writes detailed before/after log reports for unchanged addresses.

## Context
- Namespace: `SAIF.Services.AddressVerificationService`
- Assembly/package: `SAIF.Services` (packaged inside the `SAIF.SAIFCode.Core` NuGet package)

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| AddressVerificationService(...) | `public AddressVerificationService(IUnitOfWork uow, IUserProfileService prof, IAddressVerficationQueryProvider avqu, IProviderQueryProvider pqu, IVerifiedAddressProviderMatchService vams, IEnvironmentService environmentService, IProviderDataApiClient providerDataApiClient)` | Validates every collaborator is non-null via `Enforce.ArgumentNotNull` and wires them in for use by the batch address-reconciliation process. |
| StatelessProcessProviderAddressesForUpdates | `public ResultCount StatelessProcessProviderAddressesForUpdates(DateTime lastProcessDate, ILogWriter unchangedReport, ILogWriter updatedReport)` | For every active provider address updated since `lastProcessDate`, compares it to its verified address; if the comparison indicates an update is warranted, expires the old address, inserts the corrected one in a local transaction, then calls the Provider Data API to update and re-add the provider address remotely — attempting a manual local rollback if the remote call fails; returns a `ResultCount` of successes/failures. |
| GetVerifiedAddress | `public VerifiedAddress GetVerifiedAddress(long providerAddressId)` | Walks from a provider address's location-verification request through its address-verification request to the resulting verified address, returning `null` if any link in that chain is missing. |
| InsertNewProviderAddress | `public void InsertNewProviderAddress(VerifiedAddress verifiedAddress, BatchProviderAddress providerAddress, ResultCount updateProviderResults, string userId)` | Adds a new `BatchProviderAddress` row (effective tomorrow, no expiration) populated from the verified address's line/city/state/zip fields, truncating city to 25 characters, and increments the success counter. |
| IsValidUpdateableAddress | `public bool IsValidUpdateableAddress(VerifiedAddress verifiedAddress, BatchProviderAddress providerAddress, ILogWriter notUpdatedReport, ILogWriter updatedProviderAddressReport, ResultCount updateProviderResults)` | Returns `true` only when the verified and provider addresses differ in specific accepted ways (e.g. a PO-box or first-three-characters match on line 1, or a city/state/zip-only difference); returns `false` (and logs/counts a failure) for identical addresses or differences outside the accepted patterns. |
| WriteLogReports | `public void WriteLogReports(VerifiedAddress verifiedAddress, BatchProviderAddress providerAddress, ILogWriter logReport)` | Writes a fixed-width, side-by-side comparison of the provider address and verified address fields (address lines, city, state, zip) to the supplied log writer for audit/troubleshooting. |

## Behavioral notes
- `StatelessProcessProviderAddressesForUpdates` wraps the local database update in `_unitOfWork.Begin()`/`Commit()`/`Rollback()`, but the subsequent Provider Data API calls happen outside that transaction; on API failure it attempts a second, separate local transaction to restore the old address and delete the newly inserted one, and always rethrows the original exception afterward.
- `IsValidUpdateableAddress` encodes a fixed decision table of which single-field differences (line 1 via PO-box/first-three-byte matching, city, state, zip/zip+4) are considered valid grounds for an update; any other combination of differences is treated as not updateable and is logged/counted as a failure via `WriteLogReports`.
- External Provider Data API calls (`UpdateProviderAddressAsync`, `AddProviderAddressAsync`) are invoked synchronously via `.Wait()`, meaning a hang or fault in the API surfaces as a blocking exception within this batch method.

## Sources
- Services/SAIF.Services/AddressVerificationService/AddressVerificationService.cs
