Geocoding Addresses in CARTO Workflows
Converts street addresses or place names into geographic coordinates (point geometries) — the essential first step when tabular data has an address column but no spatial column. Two access paths, by scale:
- Single / ad-hoc (MCP-first): for a handful of addresses (or reverse-geocoding coordinates back to addresses), the CARTO MCP
geocodetool answers directly — operationsgeocode,reverse, andcapabilities. No workflow needed. It runs on any MCP host, including sandboxed chat hosts where the CLI can't. Prefer it for interactive requests. - Table-scale / repeatable: to geocode a whole table or build a reusable pipeline, use the Workflow pattern below. Load
carto-create-workflowfor the development process, JSON structure, and validation — it covers both paths (MCPcreate_workflow/validate_workflow/run_workflowwhen attached; thecarto workflowsCLI otherwise; routing signals incarto-basics/references/access-paths.md).
Over an API-token MCP session the ad-hoc/authoring tools are hidden (read/discovery only) — fall back to the CLI or reconnect over OAuth.
Instructions
A geocoding workflow follows this pipeline:
Source Table (with address column) -> Geocode -> (Filter successful) -> Save
Step 1: Load Source Data
Use native.gettablebyname. The input table must contain a column with address strings (e.g. address, full_address, location).
Success: Node outputs a table with at least one text column containing address data.
Step 2: Geocode
Use native.geocode with:
| Input | Description | Required |
|---|---|---|
source |
Table with address data | Yes |
address |
Column containing the address string | Yes |
country |
Country filter to improve accuracy (e.g. "United States", "United Kingdom") |
No, but strongly recommended |
The address column can contain full addresses ("123 Main St, Springfield, IL 60001") or composite values built from multiple columns (concatenate street + city + postal code in a prior native.selectexpression step).
Two output handles: The geocode component produces two separate outputs:
match: Rows where geocoding succeeded -- ageomcolumn with point geometry is added, plus aCARTO_GEOCODE_METADATAJSON column with quality info (confidence score, match type).unmatch: Rows where geocoding failed --geomis NULL.
Connect downstream nodes to the correct handle based on your needs.
Success: The geocode node is configured with the address column and (ideally) a country filter. Edges connect to the match and/or unmatch output handles.
Step 3: Filter or Review Results (optional)
For the match output:
- Optionally filter by confidence using the metadata column (e.g. extract confidence from
CARTO_GEOCODE_METADATAvianative.selectexpression).
For the unmatch output:
- Save to a separate table for review and manual correction.
- Common failure causes: typos, incomplete addresses, PO boxes, ambiguous place names.
Success: High-confidence geocoded rows are isolated; failed rows are captured for review.
Step 4: Save Results
Use native.saveastable to persist the geocoded output — the geom column holds WGS84 (EPSG:4326) points, ready for CARTO Builder or further analysis. Then validate and upload the workflow (MCP create_workflow / validate_workflow, or carto workflows create).
Geocoding Under the Hood
The workflow component wraps the CARTO Analytics Toolbox function GEOCODE_TABLE, which:
- Adds a
geomcolumn with point geometry to each row - Adds a
CARTO_GEOCODE_METADATAJSON column with quality information (confidence, match type) - Uses CARTO Location Data Services (LDS) -- each geocoded row consumes LDS quota
Check available quota by querying the Analytics Toolbox LDS_QUOTA_INFO() function. The fully-qualified name is provider-specific (BigQuery: `carto-un.carto`.LDS_QUOTA_INFO(); Snowflake: CARTO.CARTO.LDS_QUOTA_INFO(); Databricks: stored procedure in the dedicated AT schema). Load carto-create-workflow and consult references/providers/<provider>.md for the AT path on your warehouse.
Gotchas
- Two output handles:
matchandunmatch. Don't connect to the wrong one --matchhas geometries,unmatchhas NULLs. Connecting theunmatchhandle to a spatial operation will fail. - Country filter is strongly recommended. Without it, ambiguous addresses may resolve to the wrong country (e.g. "Springfield" exists in 30+ US states and in other countries). The country parameter improves both accuracy and speed.
- Address formatting matters. Well-formatted addresses produce better results:
"123 Main St, Springfield, IL 60001"works better than"123 main street springfield". Include city, state/region, and postal code when available. - Provider casing & SQL dialect. Examples in this skill use lowercase column names (BigQuery / Databricks / Postgres / Redshift convention); on Snowflake unquoted identifiers surface UPPERCASE (e.g.
CARTO_GEOCODE_METADATA,GEOM). When writing dialect-specific SQL or referencing the AT path, seecarto-create-workflow/references/providers/<provider>.md. - For large tables, consider batching. Geocoding hundreds of thousands of rows in a single run can exhaust quota or time out. Split into batches if needed.
- Failed geocodes deserve review. The
unmatchoutput is not just noise -- it often reveals data quality issues (missing postal codes, abbreviated city names, non-standard formatting) that can be fixed and re-geocoded.
Reference Templates
Academy tutorials and workflow templates covering geocoding:
| Resource | Description | URL |
|---|---|---|
| Geocoding (BigQuery AT) | Step-by-step geocoding with Analytics Toolbox for BigQuery | Academy link |
| Geocoding (Snowflake AT) | Step-by-step geocoding with Analytics Toolbox for Snowflake | Academy link |
| Workflow template: Geocode street addresses | Generating new spatial data from addresses | Academy link |
Common Variations
| Variation | How |
|---|---|
| Composite address from multiple columns | Add a native.selectexpression step before geocoding to concatenate street, city, state, zip into one column |
| Geocode + spatial join | Chain: Geocode -> match -> Spatial Join (e.g. point-in-polygon to assign regions) |
| Geocode + enrichment | Chain: Geocode -> match -> Buffer/Isochrone -> Enrich (add demographics around each geocoded point) |
| Capture failures for re-processing | Connect both match and unmatch handles to separate native.saveastable nodes |
| Filter by confidence | After geocode, use native.selectexpression to extract confidence from the metadata JSON, then filter |