Back to blog

Getting Started with GEOREFER API — Complete Developer Guide 2026

GEOREFER is a production-grade REST API for French geographic reference data. It serves over 26 million validated addresses, 16.8 million SIRENE company establishments, sub-50ms autocomplete, fuzzy search with typo tolerance, AFNOR address normalization, and a proprietary GeoTrust Score for FinTech and RegTech compliance.

This guide walks you through every step from signing up for an API key to making advanced requests. By the end, you will know how to search cities, validate addresses, normalize to AFNOR standards, query SIRENE company data, and handle errors correctly.

1. What Is GEOREFER and Why Use It?

GEOREFER is built for developers who need reliable, standardized French geographic data in their applications. Whether you are building a checkout form, running KYC checks, scoring geographic risk, or enriching a CRM with company data, GEOREFER provides a single unified API for all of it.

Core Capabilities

How It Compares

Featuregeo.api.gouv.frGoogle Address ValidationGEOREFER
SLA guaranteeNone99.9%99.9%
Address validationNoYesYes
AFNOR normalizationNoNoYes
INSEE / COG dataPartialNoFull
SIRENE companiesNoNo16.8M establishments
GeoTrust / FATF scoreNoNoYes
Price per requestFree$0.017From free

2. Prerequisites

Before you begin, make sure you have:

No SDK installation is required. GEOREFER is a standard REST API — any language that can send HTTP requests will work.

1 3. Get Your API Key

Navigate to georefer.io/#signup and register with your email address. You will receive your API key instantly via email. No credit card is required for the free tiers.

Subscription Plans

GEOREFER offers five plans to match every stage of your project:

PlanDaily LimitMonthly LimitRate/minKey FeaturesPrice
DEMO501,50010Cities, countries, searchFree
FREE1003,00010Cities, countriesFree
STARTER5,000150,00030+ Departments, regions, search49 EUR/mo
PRO50,0001,500,00060+ Companies, enrichment199 EUR/mo
ENTERPRISEUnlimitedUnlimited200+ Admin, bulk operationsCustom

Using Your API Key

Every authenticated request must include your API key in the X-Georefer-API-Key header. The base URL for all endpoints is:

https://georefer.io/geographical_repository/v1
Tip: Store your API key in an environment variable. Never hard-code it in source files that get committed to version control.

2 4. Your First Request — Search Cities

Let's start with the most common operation: searching for a city. The GET /cities endpoint supports 12 filter parameters including name, postal_code, insee_code, department_code, and country_code.

cURL

bash
curl -s "https://georefer.io/geographical_repository/v1/cities?name=Paris&country_code=FR" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" | jq .

Python

python
import requests

API_KEY = "YOUR_API_KEY"
BASE    = "https://georefer.io/geographical_repository/v1"
HEADERS = {"X-Georefer-API-Key": API_KEY}

resp = requests.get(
    f"{BASE}/cities",
    params={"name": "Paris", "country_code": "FR"},
    headers=HEADERS,
)
resp.raise_for_status()

data = resp.json()
print(f"Found {data['metadata']['total_count']} results")
for city in data["data"][:5]:
    print(f"  {city['name']} - {city['postal_code']} ({city['insee_code']})")

Node.js (ES Modules)

javascript
const API_KEY = "YOUR_API_KEY";
const BASE    = "https://georefer.io/geographical_repository/v1";

const response = await fetch(
  `${BASE}/cities?name=Paris&country_code=FR`,
  { headers: { "X-Georefer-API-Key": API_KEY } }
);

if (!response.ok) throw new Error(`HTTP ${response.status}`);

const { data, metadata } = await response.json();
console.log(`Found ${metadata.total_count} results`);
data.slice(0, 5).forEach(city =>
  console.log(`  ${city.name} - ${city.postal_code} (${city.insee_code})`)
);

Java 11+

java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(
        "https://georefer.io/geographical_repository/v1/cities"
        + "?name=Paris&country_code=FR"))
    .header("X-Georefer-API-Key", "YOUR_API_KEY")
    .GET()
    .build();

HttpResponse<String> response =
    client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.statusCode());   // 200
System.out.println(response.body());         // JSON response

Understanding the Response

Every successful response follows a standardized JSON envelope:

json
{
  "success": true,
  "data": [
    {
      "name": "PARIS",
      "postal_code": "75001",
      "insee_code": "75056",
      "department_code": "75",
      "country_code": "FR",
      "is_current_city": true
    }
  ],
  "metadata": {
    "total_count": 1,
    "page": 0,
    "page_size": 25,
    "has_next": false
  },
  "timestamp": "2026-03-20T10:30:00Z"
}

The data array contains matching records. The metadata object provides pagination details for navigating large result sets. Use page and page_size query parameters to paginate.

3 5. Validate an Address

Address validation is essential for checkout forms, KYC workflows, and data quality. The POST /addresses/validate endpoint checks a French address against the official BAN (Base Adresse Nationale) and returns a confidence score, warnings, and the proprietary GeoTrust Score for compliance use cases. For more detail, see our guide on address validation in France.

Request

bash
curl -X POST "https://georefer.io/geographical_repository/v1/addresses/validate" \
  -H "Content-Type: application/json" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" \
  -d '{
    "street_line": "15 Rue de la Paix",
    "postal_code": "75002",
    "city": "Paris",
    "country_code": "FR"
  }'

Response Explained

json
{
  "success": true,
  "data": {
    "validated_address": {
      "street_line": "15 RUE DE LA PAIX",
      "postal_code": "75002",
      "city": "PARIS",
      "department_code": "75",
      "region_code": "11",
      "country_code": "FR",
      "insee_code": "75102"
    },
    "confidence_score": 95,
    "geotrust_score": {
      "score": 92,
      "risk_level": "LOW",
      "components": {
        "confidence": 95,
        "geo_consistency": 100,
        "postal_match": 100,
        "country_risk": 0
      }
    },
    "warnings": [],
    "suggestions": []
  }
}

The GeoTrust Score is a composite value (0–100) built from four weighted sub-scores:

Risk thresholds: LOW (≥80), MEDIUM (≥60), HIGH (≥40), VERY_HIGH (<40). Most FinTech compliance teams flag addresses scoring below 60 for manual review.

Handling Invalid Addresses

When an address cannot be validated, the response still returns success: true but with a low confidence score, warning messages, and potential correction suggestions. Your application should inspect the confidence_score and warnings array to decide whether to accept, correct, or reject the address.

4 6. Normalize an Address (AFNOR)

The POST /addresses/normalize endpoint formats any French address into the official AFNOR NF Z 10-011 standard — 6 lines, maximum 38 characters per line, uppercase with no accents. This is required for official postal correspondence and many regulatory filings.

bash
curl -X POST "https://georefer.io/geographical_repository/v1/addresses/normalize" \
  -H "Content-Type: application/json" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" \
  -d '{
    "street_line": "15 rue de la paix",
    "postal_code": "75002",
    "city": "paris",
    "country_code": "FR"
  }'
json (response)
{
  "success": true,
  "data": {
    "line1": "",
    "line2": "",
    "line3": "",
    "line4": "15 RUE DE LA PAIX",
    "line5": "75002 PARIS",
    "line6": "FRANCE"
  }
}

Line 4 holds the street address, line 5 the postal code and city, and line 6 the country. Lines 1–3 are used for recipient name, organization, and building details when provided.

5 7. Search Companies (SIRENE Data)

GEOREFER indexes 16.8 million SIRENE establishments from the official INSEE database. You can search by SIREN (9 digits), SIRET (14 digits), company name, NAF activity code, postal code, or department. Company search requires a PRO plan or higher. For a deep dive into SIRENE data, read our SIRENE API guide.

Search by SIREN

bash
curl -s "https://georefer.io/geographical_repository/v1/companies?siren=552120222" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" | jq .

Search by Company Name

bash
curl -s "https://georefer.io/geographical_repository/v1/companies/search?name=michelin&limit=5" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" | jq .

Get Establishment Detail by SIRET

bash
curl -s "https://georefer.io/geographical_repository/v1/companies/55212022200013" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" | jq .

Response Fields

FieldDescriptionExample
siren9-digit company identifier552120222
siret14-digit establishment identifier55212022200013
company_nameLegal name (raison sociale)MICHELIN
naf_codeNAF activity code (APE)22.11Z
postal_codeEstablishment postal code63000
cityEstablishment cityCLERMONT-FERRAND
department_codeDepartment code63
is_headquarterWhether it is the head officetrue

6 8. City Autocomplete

The autocomplete endpoint is powered by Elasticsearch's Completion Suggester and returns results in under 50 milliseconds. It is accent-insensitive and supports prefix matching, making it perfect for search-as-you-type interfaces.

bash
curl -s "https://georefer.io/geographical_repository/v1/cities/autocomplete?q=marseil&limit=5" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" | jq .
json (response)
{
  "success": true,
  "data": [
    {"name": "MARSEILLE", "postal_code": "13001", "insee_code": "13055"},
    {"name": "MARSEILLE 1ER ARRONDISSEMENT", "postal_code": "13001", "insee_code": "13201"},
    {"name": "MARSEILLE 2EME ARRONDISSEMENT", "postal_code": "13002", "insee_code": "13202"},
    {"name": "MARSEILLETTE", "postal_code": "11800", "insee_code": "11224"},
    {"name": "MARSEILLAN", "postal_code": "34340", "insee_code": "34150"}
  ]
}

Integration Tips for Search UIs

For a working Python integration example, check out our tutorial on validating addresses with Python.

7 9. Fuzzy Search with Typo Tolerance

Real users make typos. The fuzzy search endpoint handles this gracefully using Elasticsearch's fuzziness AUTO mode, which adjusts edit distance based on the length of the input term.

bash
# Intentional typo: "Monplier" instead of "Montpellier"
curl -s "https://georefer.io/geographical_repository/v1/cities/search?q=Monplier&country_code=FR" \
  -H "X-Georefer-API-Key: YOUR_API_KEY" | jq .data[0].name

# Output: "MONTPELLIER"

The fuzzy search endpoint also supports accent-insensitive matching. Searching for "Beziers" will find "BEZIERS" regardless of whether you include the accent on the 'e'. Combined with the autocomplete endpoint, these two features let you build search UIs that handle the full range of real-world user input.

How Fuzziness Works

Input LengthMax Edit DistanceExample
1–2 characters0 (exact match)"Pa" matches "PA" only
3–5 characters1"Lile" matches "LILLE"
6+ characters2"Monplier" matches "MONTPELLIER"

10. Error Handling

All GEOREFER error responses follow the RFC 7807 application/problem+json standard. This means consistent, machine-readable error structures across every endpoint.

Common Error Codes

HTTP StatusMeaningWhen It Occurs
401UnauthorizedMissing, invalid, or expired API key
403ForbiddenFeature not included in your plan (e.g., using /companies on FREE plan)
429Too Many RequestsDaily or monthly quota exceeded, or rate limit hit
400Bad RequestInvalid request parameters or malformed JSON body
404Not FoundResource does not exist (e.g., invalid SIRET)

401 Unauthorized Example

json
{
  "success": false,
  "error": "Invalid API key",
  "status": 401
}

429 Too Many Requests Example

json
{
  "success": false,
  "error": "Daily quota exceeded",
  "plan": "FREE",
  "limit": 100,
  "retry_after": 3600
}

403 Forbidden Example

json
{
  "success": false,
  "error": "Feature 'companies' is not available in your plan (FREE). Upgrade to PRO.",
  "status": 403
}
Important: When you receive a 429 response, respect the retry_after value (in seconds). Continuing to send requests during a rate-limit window will not reset your quota and may result in temporary suspension.

Robust Error Handling in Python

python
import requests
import time

def georefer_request(endpoint, params=None, json_body=None, method="GET"):
    url = f"https://georefer.io/geographical_repository/v1{endpoint}"
    headers = {"X-Georefer-API-Key": "YOUR_API_KEY"}

    for attempt in range(3):
        if method == "GET":
            resp = requests.get(url, params=params, headers=headers)
        else:
            headers["Content-Type"] = "application/json"
            resp = requests.post(url, json=json_body, headers=headers)

        if resp.status_code == 200:
            return resp.json()
        elif resp.status_code == 429:
            retry = resp.json().get("retry_after", 60)
            print(f"Rate limited. Retrying in {retry}s...")
            time.sleep(retry)
        elif resp.status_code == 401:
            raise Exception("Invalid API key. Check your X-Georefer-API-Key header.")
        elif resp.status_code == 403:
            raise Exception(f"Feature not available: {resp.json().get('error')}")
        else:
            resp.raise_for_status()

    raise Exception("Max retries exceeded")

11. Rate Limits and Quotas

GEOREFER enforces three layers of rate protection:

  1. Per-minute rate limit (token bucket) — limits burst traffic
  2. Daily quota — total requests per calendar day (UTC)
  3. Monthly quota — total requests per calendar month

Every response includes rate-limit headers so you can monitor usage in real time:

HeaderDescription
X-RateLimit-LimitMaximum requests per minute for your plan
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
X-Georefer-PlanYour current plan name

You can also check your quota status at any time via the GET /api/usage endpoint or in the developer dashboard.

12. Complete Endpoint Reference

GEOREFER exposes 39 endpoints across 8 categories. Here is the full reference. For interactive documentation, visit the Swagger UI.

Cities & Geography (10 endpoints)

MethodEndpointDescription
GET/countriesSearch countries by name
GET/citiesSearch cities (12 filter parameters)
GET/cities/autocompleteElasticsearch autocomplete
GET/cities/searchFuzzy search with typo tolerance
GET/regionsAll 18 French regions
GET/regions/{code}Region by code with departments
GET/regions/{code}/departmentsDepartments of a region
GET/departmentsAll 101 French departments
GET/departments/{code}Department by code
GET/departments/{code}/citiesCities in a department

History & Enrichment (4 endpoints)

MethodEndpointDescription
GET/cities/{insee_code}/historyCOG commune history (mergers, splits)
GET/cities/{insee_code}/successorsSuccessor commune lookup
GET/cities/{insee_code}/enrichmentPopulation, coordinates, economics
GET/cities/statisticsAggregate city statistics

Address Validation (2 endpoints)

MethodEndpointDescription
POST/addresses/validateValidation + GeoTrust Score
POST/addresses/normalizeAFNOR NF Z 10-011 normalization

Companies (3 endpoints)

MethodEndpointDescription
GET/companiesSearch by SIREN/SIRET/name
GET/companies/searchSearch by name with geo/NAF filters
GET/companies/{siret}Establishment detail by SIRET

Search Admin (2 endpoints)

MethodEndpointDescription
POST/search/reindexFull Elasticsearch reindex
GET/search/statsIndex statistics

API Info, Usage, Billing & Admin (18 endpoints)

MethodEndpointDescription
GET/api/infoAPI key info (plan, quotas, features)
GET/api/usageSelf-service usage stats
POST/api/registerSelf-service signup
POST/api/recoverAPI key recovery via email
POST/contactContact form
POST/billing/checkoutStripe Checkout session
GET/billing/statusSubscription status
POST/billing/portalStripe Customer Portal
POST/billing/cancelCancel subscription
GET/admin/keysList all API keys
POST/admin/keysCreate API key
DELETE/admin/keys/{id}Revoke API key
GET/admin/plansList plans
GET/admin/usageGlobal usage analytics
GET/admin/usage/{id}Per-key usage stats
GET/admin/dashboardAdmin KPIs dashboard

Monitoring (no auth required)

MethodEndpointDescription
GET/monitoring/healthHealth check (PG + Redis + ES)
GET/monitoring/infoApp info and database stats

13. Frequently Asked Questions

How do I get a GEOREFER API key?

Visit georefer.io/#signup and register with your email address. You will receive your API key instantly. The DEMO plan is free and requires no credit card — it gives you 50 requests per day to test every endpoint.

What data does the GEOREFER API provide?

GEOREFER provides French geographic reference data including 37,000+ cities with INSEE codes, 101 departments, 18 regions, 250+ countries, 16.8 million SIRENE company establishments, address validation with AFNOR normalization, city autocomplete, fuzzy search, and GeoTrust scoring for compliance workflows.

Which programming languages can I use with GEOREFER?

GEOREFER is a standard REST API that works with any HTTP client. Popular choices include Python (requests), JavaScript (fetch or axios), Java (HttpClient), cURL, Go, Ruby, PHP, and C#. No SDK is required — just send HTTP requests with a custom header.

What is the GeoTrust Score in GEOREFER?

The GeoTrust Score is a composite geographic reliability score from 0 to 100, designed for FinTech and RegTech compliance. It combines four weighted sub-scores: confidence (35%), geographic consistency (25%), postal match accuracy (20%), and FATF/GAFI country risk assessment (20%). Scores above 80 indicate LOW risk, while scores below 40 indicate VERY HIGH risk.

Start Building with GEOREFER Today

Get your free API key in 30 seconds. No credit card required. 50 requests per day on the DEMO plan.

Get Your Free API Key