--- title: Batch Geocoding | Plaza Docs description: Geocode up to 1,000 addresses in a single request with Plaza's batch geocoding API. --- ## Endpoint ``` POST /api/v1/geocode/batch ``` Up to 1,000 addresses per request. Returns one GeoJSON FeatureCollection per input address, in order. ## Request body ``` { "addresses": [ "1600 Pennsylvania Ave NW, Washington DC", "350 Fifth Avenue, New York NY", "1 Infinite Loop, Cupertino CA" ] } ``` ### Options | Field | Type | Default | Description | | ----------- | --------- | ------- | ------------------------------------------------- | | `addresses` | string\[] | — | **Required.** Array of address strings (1–1,000). | ## Response ``` { "results": [ { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-77.0365, 38.8977] }, "properties": { "osm_id": 238241022, "osm_type": "way", "display_name": "The White House, 1600 Pennsylvania Avenue NW, Washington, DC 20500", "country_code": "us", "score": 0.98, "source": "structured" } } ] }, { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-73.9857, 40.7484] }, "properties": { "osm_id": 34633854, "osm_type": "way", "display_name": "Empire State Building, 350 Fifth Avenue, New York, NY 10118", "country_code": "us", "score": 0.96, "source": "structured" } } ] }, { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [-122.0308, 37.3318] }, "properties": { "osm_id": 26474008, "osm_type": "way", "display_name": "1 Infinite Loop, Cupertino, CA 95014", "country_code": "us", "score": 0.95, "source": "structured" } } ] } ], "count": 3 } ``` Unmatched addresses return an empty FeatureCollection (`"features": []`). The response always matches the input array length. ## curl example Terminal window ``` curl -X POST "https://plaza.fyi/api/v1/geocode/batch" \ -H "x-api-key: $PLAZA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "addresses": [ "10 Downing Street, London", "1600 Pennsylvania Ave NW, Washington DC", "Champs-Élysées 101, Paris" ] }' ``` ## SDK examples ### TypeScript ``` import Plaza from "@plazafyi/sdk"; const client = new Plaza(); const results = await client.v1.geocode.batch({ addresses: [ "350 Fifth Avenue, New York NY", "233 S Wacker Dr, Chicago IL", "600 Montgomery St, San Francisco CA", ], }); for (const [i, fc] of results.results.entries()) { if (fc.features.length > 0) { const [lng, lat] = fc.features[0].geometry.coordinates; console.log(`Address ${i}: ${lat}, ${lng}`); } else { console.log(`Address ${i}: no match`); } } ``` ### Python ``` import plaza import csv client = plaza.Client() # Read addresses from a CSV with open("customers.csv") as f: reader = csv.DictReader(f) addresses = [row["address"] for row in reader] # Process in chunks of 1000 for i in range(0, len(addresses), 1000): chunk = addresses[i : i + 1000] results = client.v1.geocode.batch(addresses=chunk) for j, fc in enumerate(results.results): if fc.features: coords = fc.features[0].geometry.coordinates print(f"{chunk[j]} -> {coords[1]}, {coords[0]}") else: print(f"{chunk[j]} -> NOT FOUND") ``` ### Go ``` results, err := client.V1.Geocode.Batch(ctx, plaza.V1GeocodeBatchParams{ Addresses: plaza.F([]string{ "350 Fifth Avenue, New York NY", "233 S Wacker Dr, Chicago IL", }), }) if err != nil { panic(err) } for i, fc := range results.Results { if len(fc.Features) > 0 { coords := fc.Features[0].Geometry.Coordinates fmt.Printf("Address %d: %f, %f\n", i, coords[1], coords[0]) } } ``` ## Use cases - **CSV import** — Chunk customer addresses, store locations, or delivery points into groups of 1,000 and geocode each chunk. - **Address normalization** — Geocode messy user-entered addresses to get a standardized `display_name` plus coordinates. - **Validation** — Check `score` on each result. Below 0.7 likely means typos or incomplete data; flag for manual review. ## Billing Each address counts as one API call. A batch of 500 = 500 calls. No discount or surcharge — batching reduces HTTP overhead only. ## Limits - **Max 1,000 addresses per request.** Chunk larger datasets across multiple requests. - **60-second timeout.** Batches of 1,000 typically complete in 2–5s. Reduce chunk size if you hit timeouts. - **Rate limits still apply.** A batch of 1,000 counts as 1,000 against your per-minute limit. Free tier (10 req/min) users should batch slowly or upgrade.