Validate Addresses with Power Automate: Google Maps Geocoding (Unbound Action)

Google Maps - Configuration

Overview

Address Validation for Dataverse exposes the Google Maps Geocoding API as a Dataverse unbound action named sharpxrm_VerifyWithGoogleGeocoding (display name Verify With Google Geocoding). Power Automate can call it with the standard Microsoft Dataverse connector and its Perform an unbound action step, so no custom connector is needed.

You send the action an address, and it returns a standardized address, a confidence level, and the latitude and longitude. The action does not update any record. Your flow decides what to do with the result, for example update the row only when Google returns a precise (rooftop) match. It uses the same validation engine as the Address Validation workflow steps.

Typical uses:

  • On-demand validation from the Flow menu of a model-driven app (the example in this article).
  • Scheduled clean-up of existing addresses.
  • Validating addresses created by integrations, imports or portals.

Example flow that validates a contact address with Google Maps Geocoding

Before you start

  • Address Validation for Dataverse is installed in a version that includes the Power Automate unbound actions. If sharpxrm_VerifyWithGoogleGeocoding is not listed in the Action Name drop-down, upgrade the solution.
  • A valid Address Validation license. Without one, the action returns ResultFound = Failed and the license message in VerificationDetails.
  • An active API Configuration row with Validation Service Type = Google Maps API and a Google API key that has the Geocoding API enabled. See Setup your Google Maps API Key.
  • A Microsoft Dataverse connection in Power Automate. In this example, the account behind the connection must be able to read API Configuration rows and update contacts.

How the example flow works

  1. manual (When a row is selected): runs when a user picks the flow from the Flow menu on a contact. If several contacts are selected, the flow runs once per contact.
  2. Contact ID (Compose): keeps the ID of the selected contact.
  3. Get contact (Get a row by ID): reads the current Address 1 columns of the contact.
  4. Get GoogleMaps configuration (List rows): finds the API Configuration row by name.
  5. Configuration found (Condition): stops the run with a clear error if no configuration was found.
  6. Verify with Google Geocoding (Perform an unbound action): calls the Address Validation action.
  7. Is rooftop match (Condition): overwrites Address 1 only when Google returns a ROOFTOP match. Otherwise the contact is left unchanged and the reason is recorded in the run history.

Step 1: Trigger the flow from a row

Add the Microsoft Dataverse trigger When a row is selected and set Table Name to Contacts. Turn the flow on. Users who own the flow, or with whom it is shared, can then open a contact and choose Flow > your flow name on the command bar. You can use any other trigger instead (scheduled, row added or modified, and so on). The unbound action works the same way.

When a row is selected trigger on the Contacts table

Add a Compose action named Contact ID with the contact's ID from the trigger, and a Get a row by ID action (Get contact) on Contacts. Set Select columns to the Address 1 columns you want to validate, for example address1_line1,address1_line2,address1_city,address1_stateorprovince,address1_postalcode,address1_county,address1_country.

Step 2: Find the API Configuration

The action needs the ID of the API Configuration row that holds your Google key. To avoid hard-coding a GUID, look it up by name with List rows:

FieldValue
Table nameAPIs Configuration
Select columnssharpxrm_sharpxrmconfigurationid,sharpxrm_name
Filter rowssharpxrm_name eq 'GoogleMaps' and statecode eq 0. Replace GoogleMaps with the API Config Name of your record.
Row count1

List rows action that finds the API Configuration row

Add a Condition that checks length(outputs('Get_GoogleMaps_configuration')?['body/value']) is greater than 0. In the False branch, add a Terminate action (status Failed) so a missing configuration is easy to diagnose.

Step 3: Call the unbound action

Add Microsoft Dataverse > Perform an unbound action and choose Action Name = sharpxrm_VerifyWithGoogleGeocoding. The inputs appear under Advanced parameters. Add the ones you need with Show all or from the drop-down.

Perform an unbound action configured for sharpxrm_VerifyWithGoogleGeocoding

Why does the designer say "Showing 10 of 55"? The API Configuration input is a reference to a table row, so the designer lists every column of the API Configuration table as an optional field. Only the ID field (item/APIConfiguration/sharpxrm_sharpxrmconfigurationid) needs a value. Leave the other API Configuration fields empty.

Input fields

Designer fieldRequiredWhat to enterValue used in the example
sharpxrm_sharpxrmconfiguration
item/APIConfiguration/sharpxrm_sharpxrmconfigurationid
YesThe ID (GUID) of the API Configuration row that holds the Google Maps key. The row's service type must be Google Maps API.first(outputs('Get_GoogleMaps_configuration')?['body/value'])?['sharpxrm_sharpxrmconfigurationid']
item/InputStreetAddressRecommendedHouse number and street name (address line 1). If Google cannot resolve a street address, the action returns ResultFound = Failed.Address 1: Street 1
item/InputUnitNumberOptionalApartment, suite or unit (for example Suite 200).Address 1: Street 2
item/InputCityRecommendedCity or locality.Address 1: City
item/InputStateRecommendedState or province, as a full name or an abbreviation.Address 1: State/Province
item/InputZipPostalCodeOptionalZIP or postal code. Leave it empty if unknown, because Google can infer it.Address 1: ZIP/Postal Code
item/InputCountyOptionalCounty or region.Address 1: County
item/InputCountryRecommendedCountry name or ISO code. Supplying the country greatly improves accuracy.Address 1: Country/Region
item/RecordLogicalNameOptionalLogical name of the row being validated (for example contact or account). Used only to stamp the transaction log. It does not make the action update the row.contact
item/RecordIdOptionalID of the row being validated. Like RecordLogicalName, it is used only for the transaction log.Contact ID output

All address inputs are plain text and can be empty. A transaction log (Address Validation Log) is written only when Save Transaction Logs is enabled on the API Configuration row.

Output values

Reference outputs in later steps with expressions such as outputs('Verify_with_Google_Geocoding')?['body/StreetAddress'], or pick them from the dynamic content list.

OutputDescription
ResultFoundSuccess or Failed.
VerificationDetailsOK on success. Otherwise the reason (for example an invalid license, or not enough address data).
StreetAddressStandardized house number and street, for example 1600 Amphitheatre Parkway.
UnitNumberUnit or suite, when Google returns one.
City, ZipPostalCode, CountyStandardized values, for example Mountain View, 94043, Santa Clara County.
State, CountryFull names returned by Google, for example California and United States.
FullAddressThe complete formatted address.
Latitude, LongitudeDecimal coordinates.
EntityTypeGoogle's location type: ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER or APPROXIMATE.
ConfidenceThe location type expressed as a level: HIGH, MEDIUM, LOW, VERY_LOW or UNKNOWN (see below).
EntityType (location type)ConfidenceMeaning
ROOFTOPHIGHPrecise match to the building (rooftop).
RANGE_INTERPOLATEDMEDIUMPosition interpolated between two points on the street.
GEOMETRIC_CENTERLOWCentre of a street, area or region.
APPROXIMATEVERY_LOWApproximate location only.

Step 4: Decide whether to update the row

Because the action never writes to Dataverse, add a Condition that accepts only the matches you trust. The example overwrites Address 1 only for rooftop matches:

  • body/ResultFound is equal to Success, and
  • toUpper(coalesce(outputs('Verify_with_Google_Geocoding')?['body/EntityType'], '')) is equal to ROOFTOP.

Condition that checks for a ROOFTOP match

In the True branch, add Update a row (Contacts, Row ID = Contact ID) and map the outputs to the columns:

Contact columnAction output
Address 1: Street 1 (address1_line1)StreetAddress
Address 1: Street 2 (address1_line2)UnitNumber, only when it is not empty (otherwise keep the existing value)
Address 1: CityCity
Address 1: State/ProvinceState
Address 1: ZIP/Postal CodeZipPostalCode
Address 1: CountyCounty
Address 1: Country/RegionCountry
Address 1: Latitude / LongitudeLatitude / Longitude

In the False branch, a Compose that records ResultFound, EntityType, Confidence and FullAddress makes it easy to see in the run history why a row was not updated. You could also notify the user or create a task.

Expected results

  • 1600 amphitheatre pkwy, mountain view, CA, USA returns ROOFTOP/HIGH. The contact is updated to 1600 Amphitheatre Parkway, Mountain View, California 94043, United States, with Santa Clara County and the coordinates.
  • Main Street, Toronto, ON, Canada (no house number) is not a rooftop match, so the contact is left unchanged.

Tips and troubleshooting

  • The action is not in the Action Name list: the installed solution version does not include the Power Automate actions. Upgrade Address Validation for Dataverse.
  • ResultFound is Failed: check VerificationDetails. Common causes are an invalid license, an incomplete address, or a key that does not have the Geocoding API enabled or is restricted.
  • "API Configuration reference is required" / "System configuration could not be retrieved": the API Configuration ID is empty or does not match an active row.
  • The flow is not in the Flow menu: the flow must be turned on, use When a row is selected on the same table, and be owned by or shared with the user.
  • State and country format: Geocoding returns full names (California, United States). Map the outputs differently if you prefer to keep abbreviations.
  • Cost: every run calls the Google Geocoding API and counts towards your Google usage.

Was this article helpful?