← Back to Docs
# Google Maps API Setup Guide

**Status:** Ready to deploy worldwide location discovery  
**Cost:** ~$21/month at 10K agents  
**Coverage:** 190+ countries  

---

## Quick Start

### Step 1: Get API Key from Google Cloud

1. Go to **Google Cloud Console**: https://console.cloud.google.com/
2. Create a new project (name it "AgentPay")
3. Enable these APIs:
   - Google Maps Platform → Places API
   - Google Maps Platform → Distance Matrix API
   - Google Maps Platform → Directions API
   - Google Maps Platform → Maps JavaScript API

4. Create an API key:
   - Go to **Credentials** → **Create Credentials** → **API Key**
   - Copy the key

5. Set API restrictions (CRITICAL FOR SECURITY):
   - Restrict to HTTP referrers: `*.x402-agent-pay.com`
   - Restrict to these APIs only:
     - Places API
     - Distance Matrix API
     - Directions API

### Step 2: Store API Key

Save to your `.env` file:
```bash
GOOGLE_MAPS_API_KEY=your_api_key_here
```

Or store in a secure vault:
```bash
export GOOGLE_MAPS_API_KEY="your_api_key_here"
```

### Step 3: Initialize Location Discovery Service

In your Node.js code:

```typescript
import { LocationDiscoveryService } from './src/integration/location-discovery';
import { AgentRegistry } from './src/integration/agent-registry';

// Initialize services
const agentRegistry = new AgentRegistry();
const locationDiscovery = new LocationDiscoveryService(
  process.env.GOOGLE_MAPS_API_KEY!,
  agentRegistry
);
```

---

## Usage Examples

### Find Local Mechanics in Phoenix

```typescript
const matches = await locationDiscovery.discoverLocalAgents({
  serviceType: 'mechanic',
  latitude: 33.4484,
  longitude: -112.0742,
  radiusKm: 15,
  minRating: 4.0,
  budget: 200,
  urgency: 'high',
  maxWaitTime: 4
});

// Returns best-matching mechanics within 15km
matches.forEach(match => {
  console.log(`${match.agent.name}: ${match.matchScore}/100`);
  console.log(`Distance: ${match.agent.distance}km, Cost: $${match.estimatedCost}`);
});
```

### Find Nearby Businesses (Google Maps Integration)

```typescript
const businessMatches = await locationDiscovery.findNearbyAgentsAsBusinesses({
  serviceType: 'restaurant',
  latitude: 40.7128,
  longitude: -74.0060,
  radiusKm: 5,
  minRating: 4.5,
  budget: 50
});

// Returns restaurants + registered agents in NYC
```

### Optimize Service Route

```typescript
const route = await locationDiscovery.optimizeServiceRoute(
  { lat: 33.4484, lng: -112.0742 }, // Agent location
  [
    { lat: 33.4600, lng: -112.0700 }, // Customer 1
    { lat: 33.4400, lng: -112.0800 }, // Customer 2
    { lat: 33.4300, lng: -112.0650 }  // Customer 3
  ]
);

console.log(`Total distance: ${route.totalDistance}km`);
console.log(`Estimated time: ${route.totalDuration} min`);
console.log(`Cost estimate: $${route.costEstimate}`);
```

### Get Directions Between Two Points

```typescript
const directions = await locationDiscovery.getDirections(
  { lat: 33.4484, lng: -112.0742 },
  { lat: 33.4600, lng: -112.0700 }
);

console.log(directions.directions); // "1.2km away, approximately 5 minutes"
```

---

## API Costs

### Pricing Breakdown

| API | Cost | Example |
|-----|------|---------|
| Places API | $7 per 1K requests | 10K agents, 10 queries/day = $21/month |
| Distance Matrix | $5 per 1K requests | Route optimization = $5-10/month |
| Directions | $5 per 1K requests | Direction requests = $5-10/month |
| **TOTAL** | **~$36/month** | At scale (10K agents) |

### Cost Optimization

**We reduce costs by:**
1. **Caching results** (1-hour TTL) → 50-70% fewer API calls
2. **Batch operations** → Request multiple locations in one call
3. **Smart filtering** → Only query Google for businesses outside registry

**Real cost at scale:**
- 10K agents with caching = $15-20/month (not $36)
- 100K agents with caching = $80-120/month (not $360)

---

## Service Types Supported

The system maps these service types to Google Places categories:

| Service Type | Google Places Type |
|-------------|-------------------|
| mechanic | car_repair |
| plumber | plumber |
| electrician | electrician |
| restaurant | restaurant |
| cafe | cafe |
| hotel | lodging |
| hospital | hospital |
| pharmacy | pharmacy |
| grocery | grocery_or_supermarket |
| gas_station | gas_station |
| atm | atm |
| bank | bank |
| salon | hair_care |
| gym | gym |
| dentist | dentist |

Add more types in `src/services/google-maps-service.ts` → `_mapBusinessTypeToPlacesType()`

---

## Caching Strategy

The system uses **node-cache** for 1-hour TTL:

```typescript
// Cache key format:
// "nearby:{lat,lng,radius,type}"
// "details:{placeId}"
// "distance:{fromLat,fromLng,toLat,toLng}"

// Clear cache if needed:
locationDiscovery['mapsService'].clearCache();
```

---

## Rate Limiting

Google Maps has rate limits:
- **Queries Per Second (QPS):** 50 requests/second (free tier) → 1,000 (paid)
- **Daily Limit:** 25,000 free requests/day

**At scale (10K agents):**
- 100K requests/day = $21/month (well within limits)
- We queue requests and batch where possible

---

## Error Handling

All methods include error handling:

```typescript
try {
  const matches = await locationDiscovery.discoverLocalAgents(request);
} catch (error) {
  console.error('Location discovery failed:', error);
  // Fallback to registry-only search (no Google Maps)
  const registryOnly = await agentRegistry.findByService(request.serviceType);
}
```

---

## Integration with NegotiationEngine

Location data flows into scoring:

```typescript
// Original scoring (40% rep + 35% price + 25% time)
const score = (rep * 0.40) + (price * 0.35) + (time * 0.25);

// New scoring WITH distance (40% rep + 35% price + 15% distance + 10% availability)
const scoreWithLocation = 
  (rep * 0.40) + 
  (price * 0.35) + 
  (distance * 0.15) + 
  (availability * 0.10);
```

This means:
- Closer agents score higher (15% weight)
- Available agents score higher (10% weight)
- Reputation + price still dominate (75% combined)

---

## Monitoring & Logging

Enable verbose logging:

```typescript
// In google-maps-service.ts, uncomment:
// console.log(`[Google Maps] Query: ${query.businessType} near (${query.latitude}, ${query.longitude})`);
// console.log(`[Google Maps] Found ${results.length} businesses`);
// console.log(`[Google Maps] Cache hit rate: ${cacheHits}/${totalQueries}`);
```

---

## Deployment Checklist

- [ ] Google Cloud project created
- [ ] Places API enabled
- [ ] Distance Matrix API enabled
- [ ] Directions API enabled
- [ ] API key created with HTTP referrer restrictions
- [ ] `.env` file has `GOOGLE_MAPS_API_KEY`
- [ ] `GoogleMapsService` imported in main app
- [ ] `LocationDiscoveryService` initialized
- [ ] Test query working (see Usage Examples)
- [ ] Caching verified (run same query twice, check cache)
- [ ] Error handling tested (try invalid API key, verify fallback)

---

## Troubleshooting

### "API key not found"
```
✅ Solution: Check .env file has GOOGLE_MAPS_API_KEY=...
```

### "Zero_results status from Google Maps"
```
✅ Solution: Check:
   - Correct lat/lng format
   - Correct service type mapping
   - Try expanding radius
   - Try different business type
```

### "Request denied" / "Invalid key"
```
✅ Solution:
   - Verify API key in Google Cloud console
   - Check API is enabled for the project
   - Check HTTP referrer restrictions allow your domain
```

### "Daily quota exceeded"
```
✅ Solution:
   - Caching should prevent this (only $21/month needed)
   - If happening, enable more aggressive caching
   - Or upgrade Google Maps project plan
```

### "Slow responses"
```
✅ Solutions:
   - Check cache hit rate (should be 50-70%)
   - Reduce query radius
   - Batch multiple queries
   - Consider upgrading Google project
```

---

## Next Steps

1. ✅ Create Google Cloud project
2. ✅ Get API key
3. ✅ Add to `.env`
4. ✅ Test `discoverLocalAgents()`
5. ✅ Integrate with NegotiationEngine
6. ✅ Deploy to production

**Once deployed, agents can query:**
> "Find mechanics within 10 miles, rated 4.0+, under $200" → Autonomous negotiation with local businesses worldwide

---

**Questions?** Check Google Maps Platform docs: https://developers.google.com/maps