French address verification API for AI agents
Check that a French address really exists and normalize it: this endpoint geocodes free-text addresses against the Base Adresse Nationale (BAN), France's official address database, served by api-adresse.data.gouv.fr (Etalab/IGN, continuously updated). Each match returns the normalized label, a confidence score, latitude/longitude, street, postcode, city, INSEE citycode and administrative context; a reverse mode turns coordinates back into the nearest address.
At $0.001 per call in USDC it is priced for high-volume agent use: no account, no API key. An address with no match returns 400 and is never billed - you only pay when the BAN actually confirms something. Responses are cached for 24 hours.
Endpoint
GET /v1/fr/geocode — $0.001 per call (USDC on Base, x402). Also available as the MCP tool verify_address_fr on https://data.greeneris.io/mcp.
Parameters
| Param | Description |
|---|---|
q | Free-text French address, 3-200 chars (forward mode), e.g. '8 boulevard du port amiens' |
lat | Latitude in decimal degrees (reverse mode, together with lon) |
lon | Longitude in decimal degrees (reverse mode, together with lat) |
type | Restrict match type: housenumber, street, locality or municipality (optional) |
citycode | Filter by 5-character INSEE city code, e.g. 80021 (optional) |
limit | Max matches, 1-10 (default 3) |
Example
curl -i "https://data.greeneris.io/v1/fr/geocode?q=8+boulevard+du+port+amiens&limit=1"
# HTTP/1.1 402 Payment Required + machine-readable quote
# (any x402 client pays the quote and retries automatically)Or pay and read the answer from code (pip install "x402[httpx,evm]"):
import asyncio, os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm.exact import register_exact_evm_client
buyer = Account.from_key(os.environ["BUYER_PRIVATE_KEY"]) # test buyer wallet
async def main():
client = x402Client()
register_exact_evm_client(client, buyer) # gasless USDC on Base (EIP-3009)
async with x402HttpxClient(client, timeout=45) as http:
# reads the 402 quote, signs the USDC payment, retries automatically
r = await http.get("https://data.greeneris.io/v1/fr/geocode?q=8+boulevard+du+port+amiens&limit=1")
print(r.status_code, (await r.aread()).decode())
asyncio.run(main())Response after payment:
{"ok": true, "data": {"mode": "search", "query": "8 boulevard du port amiens", "count": 1, "matches": [{"label": "8 Boulevard du Port 80000 Amiens", "score": 0.97072, "lat": 49.897442, "lon": 2.290084, "type": "housenumber", "housenumber": "8", "street": "Boulevard du Port", "postcode": "80000", "city": "Amiens", "citycode": "80021", "context": "80, Somme, Hauts-de-France"}]}}What agents use it for
- Onboarding forms: verify a customer's French address is real and store the normalized BAN label
- Deduplicate CRM records by resolving address variants to the same INSEE citycode and coordinates
- Reverse-geocode GPS points from delivery or field data into postal addresses
How payment works
Call the endpoint: you get HTTP 402 with a signed quote (price, receiving address, network). Your agent pays a few tenths of a cent in USDC on Base (gasless, EIP-3009) and retries - one round trip, no account, no API key. Settlement only happens after a successful answer. Full catalog: llms.txt.